1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s
4 ; Canonicalization of unsigned saturated subtraction idioms to
5 ; usub.sat() intrinsics is tested here.
8 declare void @usei32(i32)
9 declare void @usei1(i1)
11 ; usub_sat((sub nuw C1, A), C2) to usub_sat(usub_sat(C1 - C2), A)
12 define i32 @usub_sat_C1_C2(i32 %a){
13 ; CHECK-LABEL: @usub_sat_C1_C2(
14 ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.usub.sat.i32(i32 50, i32 [[A:%.*]])
15 ; CHECK-NEXT: ret i32 [[COND]]
17 %add = sub nuw i32 64, %a
18 %cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)
22 define i32 @usub_sat_C1_C2_produce_0(i32 %a){
23 ; CHECK-LABEL: @usub_sat_C1_C2_produce_0(
24 ; CHECK-NEXT: ret i32 0
26 %add = sub nuw i32 14, %a
27 %cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)
31 define i32 @usub_sat_C1_C2_produce_0_too(i32 %a){
32 ; CHECK-LABEL: @usub_sat_C1_C2_produce_0_too(
33 ; CHECK-NEXT: ret i32 0
35 %add = sub nuw i32 12, %a
36 %cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)
41 define <2 x i16> @usub_sat_C1_C2_splat(<2 x i16> %a) {
42 ; CHECK-LABEL: @usub_sat_C1_C2_splat(
43 ; CHECK-NEXT: [[COND:%.*]] = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> <i16 50, i16 50>, <2 x i16> [[A:%.*]])
44 ; CHECK-NEXT: ret <2 x i16> [[COND]]
46 %add = sub nuw <2 x i16> <i16 64, i16 64>, %a
47 %cond = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %add, <2 x i16> <i16 14, i16 14>)
51 define <2 x i16> @usub_sat_C1_C2_non_splat(<2 x i16> %a) {
52 ; CHECK-LABEL: @usub_sat_C1_C2_non_splat(
53 ; CHECK-NEXT: [[COND:%.*]] = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> <i16 30, i16 50>, <2 x i16> [[A:%.*]])
54 ; CHECK-NEXT: ret <2 x i16> [[COND]]
56 %add = sub nuw <2 x i16> <i16 50, i16 64>, %a
57 %cond = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %add, <2 x i16> <i16 20, i16 14>)
61 define <2 x i16> @usub_sat_C1_C2_splat_produce_0(<2 x i16> %a){
62 ; CHECK-LABEL: @usub_sat_C1_C2_splat_produce_0(
63 ; CHECK-NEXT: ret <2 x i16> zeroinitializer
65 %add = sub nuw <2 x i16> <i16 14, i16 14>, %a
66 %cond = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %add, <2 x i16> <i16 14, i16 14>)
70 define <2 x i16> @usub_sat_C1_C2_splat_produce_0_too(<2 x i16> %a){
71 ; CHECK-LABEL: @usub_sat_C1_C2_splat_produce_0_too(
72 ; CHECK-NEXT: ret <2 x i16> zeroinitializer
74 %add = sub nuw <2 x i16> <i16 12, i16 12>, %a
75 %cond = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %add, <2 x i16> <i16 14, i16 14>)
79 define <2 x i16> @usub_sat_C1_C2_non_splat_produce_0_too(<2 x i16> %a){
80 ; CHECK-LABEL: @usub_sat_C1_C2_non_splat_produce_0_too(
81 ; CHECK-NEXT: ret <2 x i16> zeroinitializer
83 %add = sub nuw <2 x i16> <i16 12, i16 13>, %a
84 %cond = call <2 x i16> @llvm.usub.sat.v2i16(<2 x i16> %add, <2 x i16> <i16 14, i16 15>)
88 ; negative tests this souldn't work
89 define i32 @usub_sat_C1_C2_without_nuw(i32 %a){
90 ; CHECK-LABEL: @usub_sat_C1_C2_without_nuw(
91 ; CHECK-NEXT: [[ADD:%.*]] = sub i32 12, [[A:%.*]]
92 ; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[ADD]], i32 14)
93 ; CHECK-NEXT: ret i32 [[COND]]
96 %cond = call i32 @llvm.usub.sat.i32(i32 %add, i32 14)
100 ; (a > b) ? a - b : 0 -> usub.sat(a, b)
102 define i64 @max_sub_ugt(i64 %a, i64 %b) {
103 ; CHECK-LABEL: @max_sub_ugt(
104 ; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])
105 ; CHECK-NEXT: ret i64 [[SEL]]
107 %cmp = icmp ugt i64 %a, %b
108 %sub = sub i64 %a, %b
109 %sel = select i1 %cmp, i64 %sub ,i64 0
113 ; (a >= b) ? a - b : 0 -> usub.sat(a, b)
115 define i64 @max_sub_uge(i64 %a, i64 %b) {
116 ; CHECK-LABEL: @max_sub_uge(
117 ; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])
118 ; CHECK-NEXT: ret i64 [[SEL]]
120 %cmp = icmp uge i64 %a, %b
121 %sub = sub i64 %a, %b
122 %sel = select i1 %cmp, i64 %sub ,i64 0
126 define i64 @max_sub_uge_extrause1(i64 %a, i64 %b) {
127 ; CHECK-LABEL: @max_sub_uge_extrause1(
128 ; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[A:%.*]], [[B:%.*]]
129 ; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]])
130 ; CHECK-NEXT: call void @use(i64 [[SUB]])
131 ; CHECK-NEXT: ret i64 [[SEL]]
133 %cmp = icmp uge i64 %a, %b
134 %sub = sub i64 %a, %b
135 %sel = select i1 %cmp, i64 %sub ,i64 0
136 call void @use(i64 %sub)
140 define i64 @max_sub_uge_extrause2(i64 %a, i64 %b) {
141 ; CHECK-LABEL: @max_sub_uge_extrause2(
142 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[A:%.*]], [[B:%.*]]
143 ; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]])
144 ; CHECK-NEXT: call void @usei1(i1 [[CMP]])
145 ; CHECK-NEXT: ret i64 [[SEL]]
147 %cmp = icmp uge i64 %a, %b
148 %sub = sub i64 %a, %b
149 %sel = select i1 %cmp, i64 %sub ,i64 0
150 call void @usei1(i1 %cmp)
154 define i64 @max_sub_uge_extrause3(i64 %a, i64 %b) {
155 ; CHECK-LABEL: @max_sub_uge_extrause3(
156 ; CHECK-NEXT: [[CMP:%.*]] = icmp uge i64 [[A:%.*]], [[B:%.*]]
157 ; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[A]], [[B]]
158 ; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]])
159 ; CHECK-NEXT: call void @use(i64 [[SUB]])
160 ; CHECK-NEXT: call void @usei1(i1 [[CMP]])
161 ; CHECK-NEXT: ret i64 [[SEL]]
163 %cmp = icmp uge i64 %a, %b
164 %sub = sub i64 %a, %b
165 %sel = select i1 %cmp, i64 %sub ,i64 0
166 call void @use(i64 %sub)
167 call void @usei1(i1 %cmp)
171 ; Again, with vectors:
172 ; (a > b) ? a - b : 0 -> usub.sat(a, b)
174 define <4 x i32> @max_sub_ugt_vec(<4 x i32> %a, <4 x i32> %b) {
175 ; CHECK-LABEL: @max_sub_ugt_vec(
176 ; CHECK-NEXT: [[SEL:%.*]] = call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]])
177 ; CHECK-NEXT: ret <4 x i32> [[SEL]]
179 %cmp = icmp ugt <4 x i32> %a, %b
180 %sub = sub <4 x i32> %a, %b
181 %sel = select <4 x i1> %cmp, <4 x i32> %sub, <4 x i32> zeroinitializer
185 ; Use extra ops to thwart icmp swapping canonicalization.
186 ; (b < a) ? a - b : 0 -> usub.sat(a, b)
188 define i64 @max_sub_ult(i64 %a, i64 %b) {
189 ; CHECK-LABEL: @max_sub_ult(
190 ; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])
191 ; CHECK-NEXT: [[EXTRASUB:%.*]] = sub i64 [[B]], [[A]]
192 ; CHECK-NEXT: call void @use(i64 [[EXTRASUB]])
193 ; CHECK-NEXT: ret i64 [[SEL]]
195 %cmp = icmp ult i64 %b, %a
196 %sub = sub i64 %a, %b
197 %sel = select i1 %cmp, i64 %sub ,i64 0
198 %extrasub = sub i64 %b, %a
199 call void @use(i64 %extrasub)
203 ; (b > a) ? 0 : a - b -> usub.sat(a, b)
205 define i64 @max_sub_ugt_sel_swapped(i64 %a, i64 %b) {
206 ; CHECK-LABEL: @max_sub_ugt_sel_swapped(
207 ; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])
208 ; CHECK-NEXT: [[EXTRASUB:%.*]] = sub i64 [[B]], [[A]]
209 ; CHECK-NEXT: call void @use(i64 [[EXTRASUB]])
210 ; CHECK-NEXT: ret i64 [[SEL]]
212 %cmp = icmp ugt i64 %b, %a
213 %sub = sub i64 %a, %b
214 %sel = select i1 %cmp, i64 0 ,i64 %sub
215 %extrasub = sub i64 %b, %a
216 call void @use(i64 %extrasub)
220 ; (a < b) ? 0 : a - b -> usub.sat(a, b)
222 define i64 @max_sub_ult_sel_swapped(i64 %a, i64 %b) {
223 ; CHECK-LABEL: @max_sub_ult_sel_swapped(
224 ; CHECK-NEXT: [[SEL:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])
225 ; CHECK-NEXT: ret i64 [[SEL]]
227 %cmp = icmp ult i64 %a, %b
228 %sub = sub i64 %a, %b
229 %sel = select i1 %cmp, i64 0 ,i64 %sub
233 ; ((a > b) ? b - a : 0) -> -usub.sat(a, b)
235 define i64 @neg_max_sub_ugt(i64 %a, i64 %b) {
236 ; CHECK-LABEL: @neg_max_sub_ugt(
237 ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])
238 ; CHECK-NEXT: [[SEL:%.*]] = sub i64 0, [[TMP1]]
239 ; CHECK-NEXT: [[EXTRASUB:%.*]] = sub i64 [[A]], [[B]]
240 ; CHECK-NEXT: call void @use(i64 [[EXTRASUB]])
241 ; CHECK-NEXT: ret i64 [[SEL]]
243 %cmp = icmp ugt i64 %a, %b
244 %sub = sub i64 %b, %a
245 %sel = select i1 %cmp, i64 %sub ,i64 0
246 %extrasub = sub i64 %a, %b
247 call void @use(i64 %extrasub)
251 ; ((b < a) ? b - a : 0) -> -usub.sat(a, b)
253 define i64 @neg_max_sub_ult(i64 %a, i64 %b) {
254 ; CHECK-LABEL: @neg_max_sub_ult(
255 ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])
256 ; CHECK-NEXT: [[SEL:%.*]] = sub i64 0, [[TMP1]]
257 ; CHECK-NEXT: ret i64 [[SEL]]
259 %cmp = icmp ult i64 %b, %a
260 %sub = sub i64 %b, %a
261 %sel = select i1 %cmp, i64 %sub ,i64 0
265 ; ((b > a) ? 0 : b - a) -> -usub.sat(a, b)
267 define i64 @neg_max_sub_ugt_sel_swapped(i64 %a, i64 %b) {
268 ; CHECK-LABEL: @neg_max_sub_ugt_sel_swapped(
269 ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])
270 ; CHECK-NEXT: [[SEL:%.*]] = sub i64 0, [[TMP1]]
271 ; CHECK-NEXT: ret i64 [[SEL]]
273 %cmp = icmp ugt i64 %b, %a
274 %sub = sub i64 %b, %a
275 %sel = select i1 %cmp, i64 0 ,i64 %sub
279 define i64 @neg_max_sub_ugt_sel_swapped_extrause1(i64 %a, i64 %b) {
280 ; CHECK-LABEL: @neg_max_sub_ugt_sel_swapped_extrause1(
281 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[B:%.*]], [[A:%.*]]
282 ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]])
283 ; CHECK-NEXT: [[SEL:%.*]] = sub i64 0, [[TMP1]]
284 ; CHECK-NEXT: call void @usei1(i1 [[CMP]])
285 ; CHECK-NEXT: ret i64 [[SEL]]
287 %cmp = icmp ugt i64 %b, %a
288 %sub = sub i64 %b, %a
289 %sel = select i1 %cmp, i64 0 ,i64 %sub
290 call void @usei1(i1 %cmp)
294 define i64 @neg_max_sub_ugt_sel_swapped_extrause2(i64 %a, i64 %b) {
295 ; CHECK-LABEL: @neg_max_sub_ugt_sel_swapped_extrause2(
296 ; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[B:%.*]], [[A:%.*]]
297 ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A]], i64 [[B]])
298 ; CHECK-NEXT: [[SEL:%.*]] = sub i64 0, [[TMP1]]
299 ; CHECK-NEXT: call void @use(i64 [[SUB]])
300 ; CHECK-NEXT: ret i64 [[SEL]]
302 %cmp = icmp ugt i64 %b, %a
303 %sub = sub i64 %b, %a
304 %sel = select i1 %cmp, i64 0 ,i64 %sub
305 call void @use(i64 %sub)
309 define i64 @neg_max_sub_ugt_sel_swapped_extrause3(i64 %a, i64 %b) {
310 ; CHECK-LABEL: @neg_max_sub_ugt_sel_swapped_extrause3(
311 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[B:%.*]], [[A:%.*]]
312 ; CHECK-NEXT: [[SUB:%.*]] = sub i64 [[B]], [[A]]
313 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i64 0, i64 [[SUB]]
314 ; CHECK-NEXT: call void @use(i64 [[SUB]])
315 ; CHECK-NEXT: call void @usei1(i1 [[CMP]])
316 ; CHECK-NEXT: ret i64 [[SEL]]
318 %cmp = icmp ugt i64 %b, %a
319 %sub = sub i64 %b, %a
320 %sel = select i1 %cmp, i64 0 ,i64 %sub
321 call void @use(i64 %sub)
322 call void @usei1(i1 %cmp)
326 ; ((a < b) ? 0 : b - a) -> -usub.sat(a, b)
328 define i64 @neg_max_sub_ult_sel_swapped(i64 %a, i64 %b) {
329 ; CHECK-LABEL: @neg_max_sub_ult_sel_swapped(
330 ; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.usub.sat.i64(i64 [[A:%.*]], i64 [[B:%.*]])
331 ; CHECK-NEXT: [[SEL:%.*]] = sub i64 0, [[TMP1]]
332 ; CHECK-NEXT: [[EXTRASUB:%.*]] = sub i64 [[A]], [[B]]
333 ; CHECK-NEXT: call void @use(i64 [[EXTRASUB]])
334 ; CHECK-NEXT: ret i64 [[SEL]]
336 %cmp = icmp ult i64 %a, %b
337 %sub = sub i64 %b, %a
338 %sel = select i1 %cmp, i64 0 ,i64 %sub
339 %extrasub = sub i64 %a, %b
340 call void @use(i64 %extrasub)
344 define i32 @max_sub_ugt_c1(i32 %a) {
345 ; CHECK-LABEL: @max_sub_ugt_c1(
346 ; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 1)
347 ; CHECK-NEXT: ret i32 [[SEL]]
349 %cmp = icmp ugt i32 %a, 1
350 %sub = add i32 %a, -1
351 %sel = select i1 %cmp, i32 %sub ,i32 0
355 define i32 @max_sub_ugt_c01(i32 %a) {
356 ; CHECK-LABEL: @max_sub_ugt_c01(
357 ; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 1)
358 ; CHECK-NEXT: ret i32 [[SEL]]
360 %cmp = icmp ugt i32 %a, 0
361 %sub = add i32 %a, -1
362 %sel = select i1 %cmp, i32 %sub ,i32 0
366 define i32 @max_sub_ugt_c10(i32 %a) {
367 ; CHECK-LABEL: @max_sub_ugt_c10(
368 ; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 10)
369 ; CHECK-NEXT: ret i32 [[SEL]]
371 %cmp = icmp ugt i32 %a, 10
372 %sub = add i32 %a, -10
373 %sel = select i1 %cmp, i32 %sub, i32 0
377 define i32 @max_sub_ugt_c910(i32 %a) {
378 ; CHECK-LABEL: @max_sub_ugt_c910(
379 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 9
380 ; CHECK-NEXT: [[SUB:%.*]] = add i32 [[A]], -10
381 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 0
382 ; CHECK-NEXT: ret i32 [[SEL]]
384 %cmp = icmp ugt i32 %a, 9
385 %sub = add i32 %a, -10
386 %sel = select i1 %cmp, i32 %sub, i32 0
390 define i32 @max_sub_ugt_c1110(i32 %a) {
391 ; CHECK-LABEL: @max_sub_ugt_c1110(
392 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 11
393 ; CHECK-NEXT: [[SUB:%.*]] = add i32 [[A]], -10
394 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 0
395 ; CHECK-NEXT: ret i32 [[SEL]]
397 %cmp = icmp ugt i32 %a, 11
398 %sub = add i32 %a, -10
399 %sel = select i1 %cmp, i32 %sub, i32 0
403 define i32 @max_sub_ugt_c0(i32 %a) {
404 ; CHECK-LABEL: @max_sub_ugt_c0(
405 ; CHECK-NEXT: ret i32 0
407 %cmp = icmp ugt i32 %a, -1
409 %sel = select i1 %cmp, i32 %sub, i32 0
413 define i32 @max_sub_ugt_cmiss(i32 %a) {
414 ; CHECK-LABEL: @max_sub_ugt_cmiss(
415 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 1
416 ; CHECK-NEXT: [[SUB:%.*]] = add i32 [[A]], -2
417 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 0
418 ; CHECK-NEXT: ret i32 [[SEL]]
420 %cmp = icmp ugt i32 %a, 1
421 %sub = add i32 %a, -2
422 %sel = select i1 %cmp, i32 %sub, i32 0
426 define i32 @max_sub_ult_c1(i32 %a) {
427 ; CHECK-LABEL: @max_sub_ult_c1(
428 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
429 ; CHECK-NEXT: [[SEL:%.*]] = sext i1 [[CMP]] to i32
430 ; CHECK-NEXT: ret i32 [[SEL]]
432 %cmp = icmp ult i32 %a, 1
433 %sub = add i32 %a, -1
434 %sel = select i1 %cmp, i32 %sub, i32 0
438 define i32 @max_sub_ult_c2(i32 %a) {
439 ; CHECK-LABEL: @max_sub_ult_c2(
440 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 2, i32 [[A:%.*]])
441 ; CHECK-NEXT: [[SEL:%.*]] = sub nsw i32 0, [[TMP1]]
442 ; CHECK-NEXT: ret i32 [[SEL]]
444 %cmp = icmp ult i32 %a, 2
445 %sub = add i32 %a, -2
446 %sel = select i1 %cmp, i32 %sub, i32 0
450 define i32 @max_sub_ult_c2_oneuseicmp(i32 %a) {
451 ; CHECK-LABEL: @max_sub_ult_c2_oneuseicmp(
452 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 2
453 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 2, i32 [[A]])
454 ; CHECK-NEXT: [[SEL:%.*]] = sub nsw i32 0, [[TMP1]]
455 ; CHECK-NEXT: call void @usei1(i1 [[CMP]])
456 ; CHECK-NEXT: ret i32 [[SEL]]
458 %cmp = icmp ult i32 %a, 2
459 %sub = add i32 %a, -2
460 %sel = select i1 %cmp, i32 %sub, i32 0
461 call void @usei1(i1 %cmp)
465 define i32 @max_sub_ult_c2_oneusesub(i32 %a) {
466 ; CHECK-LABEL: @max_sub_ult_c2_oneusesub(
467 ; CHECK-NEXT: [[SUB:%.*]] = add i32 [[A:%.*]], -2
468 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 2, i32 [[A]])
469 ; CHECK-NEXT: [[SEL:%.*]] = sub nsw i32 0, [[TMP1]]
470 ; CHECK-NEXT: call void @usei32(i32 [[SUB]])
471 ; CHECK-NEXT: ret i32 [[SEL]]
473 %cmp = icmp ult i32 %a, 2
474 %sub = add i32 %a, -2
475 %sel = select i1 %cmp, i32 %sub, i32 0
476 call void @usei32(i32 %sub)
480 define i32 @max_sub_ult_c32(i32 %a) {
481 ; CHECK-LABEL: @max_sub_ult_c32(
482 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 3
483 ; CHECK-NEXT: [[SUB:%.*]] = add i32 [[A]], -2
484 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 0
485 ; CHECK-NEXT: ret i32 [[SEL]]
487 %cmp = icmp ult i32 %a, 3
488 %sub = add i32 %a, -2
489 %sel = select i1 %cmp, i32 %sub, i32 0
493 define i32 @max_sub_ugt_c32(i32 %a) {
494 ; CHECK-LABEL: @max_sub_ugt_c32(
495 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 3
496 ; CHECK-NEXT: [[SUB:%.*]] = add i32 [[A]], -2
497 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 0
498 ; CHECK-NEXT: ret i32 [[SEL]]
500 %cmp = icmp ugt i32 3, %a
501 %sub = add i32 %a, -2
502 %sel = select i1 %cmp, i32 %sub, i32 0
506 define i32 @max_sub_uge_c32(i32 %a) {
507 ; CHECK-LABEL: @max_sub_uge_c32(
508 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 3
509 ; CHECK-NEXT: [[SUB:%.*]] = add i32 [[A]], -2
510 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 0
511 ; CHECK-NEXT: ret i32 [[SEL]]
513 %cmp = icmp uge i32 2, %a
514 %sub = add i32 %a, -2
515 %sel = select i1 %cmp, i32 %sub, i32 0
519 define i32 @max_sub_ult_c12(i32 %a) {
520 ; CHECK-LABEL: @max_sub_ult_c12(
521 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
522 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 -2, i32 0
523 ; CHECK-NEXT: ret i32 [[SEL]]
525 %cmp = icmp ult i32 %a, 1
526 %sub = add i32 %a, -2
527 %sel = select i1 %cmp, i32 %sub, i32 0
531 define i32 @max_sub_ult_c0(i32 %a) {
532 ; CHECK-LABEL: @max_sub_ult_c0(
533 ; CHECK-NEXT: ret i32 0
535 %cmp = icmp ult i32 %a, 0
536 %sub = add i32 %a, -1
537 %sel = select i1 %cmp, i32 %sub, i32 0