[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / unrecognized_three-way-comparison.ll
blob14e0b5573946b0090be3d29973fe65204db834f1
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
6 declare void @foo(i32 %x)
8 define i32 @compare_against_arbitrary_value(i32 %x, i32 %c) {
9 ; CHECK-LABEL: @compare_against_arbitrary_value(
10 ; CHECK-NEXT:  entry:
11 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], [[C:%.*]]
12 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
13 ; CHECK:       callfoo:
14 ; CHECK-NEXT:    call void @foo(i32 1)
15 ; CHECK-NEXT:    br label [[EXIT]]
16 ; CHECK:       exit:
17 ; CHECK-NEXT:    ret i32 42
20 entry:
21   %cmp1 = icmp eq i32 %x, %c
22   %cmp2 = icmp slt i32 %x, %c
23   %select1 = select i1 %cmp2, i32 -1, i32 1
24   %select2 = select i1 %cmp1, i32 0, i32 %select1
25   %cond = icmp sgt i32 %select2, 0
26   br i1 %cond, label %callfoo, label %exit
28 callfoo:
29   call void @foo(i32 %select2)
30   br label %exit
32 exit:
33   ret i32 42
36 define i32 @compare_against_zero(i32 %x) {
37 ; CHECK-LABEL: @compare_against_zero(
38 ; CHECK-NEXT:  entry:
39 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 0
40 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
41 ; CHECK:       callfoo:
42 ; CHECK-NEXT:    call void @foo(i32 1)
43 ; CHECK-NEXT:    br label [[EXIT]]
44 ; CHECK:       exit:
45 ; CHECK-NEXT:    ret i32 42
48 entry:
49   %cmp1 = icmp eq i32 %x, 0
50   %cmp2 = icmp slt i32 %x, 0
51   %select1 = select i1 %cmp2, i32 -1, i32 1
52   %select2 = select i1 %cmp1, i32 0, i32 %select1
53   %cond = icmp sgt i32 %select2, 0
54   br i1 %cond, label %callfoo, label %exit
56 callfoo:
57   call void @foo(i32 %select2)
58   br label %exit
60 exit:
61   ret i32 42
64 define i32 @compare_against_one(i32 %x) {
65 ; CHECK-LABEL: @compare_against_one(
66 ; CHECK-NEXT:  entry:
67 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 1
68 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
69 ; CHECK:       callfoo:
70 ; CHECK-NEXT:    call void @foo(i32 1)
71 ; CHECK-NEXT:    br label [[EXIT]]
72 ; CHECK:       exit:
73 ; CHECK-NEXT:    ret i32 42
76 entry:
77   %cmp1 = icmp eq i32 %x, 1
78   %cmp2 = icmp slt i32 %x, 1
79   %select1 = select i1 %cmp2, i32 -1, i32 1
80   %select2 = select i1 %cmp1, i32 0, i32 %select1
81   %cond = icmp sgt i32 %select2, 0
82   br i1 %cond, label %callfoo, label %exit
84 callfoo:
85   call void @foo(i32 %select2)
86   br label %exit
88 exit:
89   ret i32 42
92 define i32 @compare_against_two(i32 %x) {
93 ; CHECK-LABEL: @compare_against_two(
94 ; CHECK-NEXT:  entry:
95 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 2
96 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
97 ; CHECK:       callfoo:
98 ; CHECK-NEXT:    call void @foo(i32 1)
99 ; CHECK-NEXT:    br label [[EXIT]]
100 ; CHECK:       exit:
101 ; CHECK-NEXT:    ret i32 42
104 entry:
105   %cmp1 = icmp eq i32 %x, 2
106   %cmp2 = icmp slt i32 %x, 2
107   %select1 = select i1 %cmp2, i32 -1, i32 1
108   %select2 = select i1 %cmp1, i32 0, i32 %select1
109   %cond = icmp sgt i32 %select2, 0
110   br i1 %cond, label %callfoo, label %exit
112 callfoo:
113   call void @foo(i32 %select2)
114   br label %exit
116 exit:
117   ret i32 42
120 define i32 @compare_against_three(i32 %x) {
121 ; CHECK-LABEL: @compare_against_three(
122 ; CHECK-NEXT:  entry:
123 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 3
124 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
125 ; CHECK:       callfoo:
126 ; CHECK-NEXT:    call void @foo(i32 1)
127 ; CHECK-NEXT:    br label [[EXIT]]
128 ; CHECK:       exit:
129 ; CHECK-NEXT:    ret i32 42
132 entry:
133   %cmp1 = icmp eq i32 %x, 3
134   %cmp2 = icmp slt i32 %x, 3
135   %select1 = select i1 %cmp2, i32 -1, i32 1
136   %select2 = select i1 %cmp1, i32 0, i32 %select1
137   %cond = icmp sgt i32 %select2, 0
138   br i1 %cond, label %callfoo, label %exit
140 callfoo:
141   call void @foo(i32 %select2)
142   br label %exit
144 exit:
145   ret i32 42
148 define i32 @compare_against_four(i32 %x) {
149 ; CHECK-LABEL: @compare_against_four(
150 ; CHECK-NEXT:  entry:
151 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 4
152 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
153 ; CHECK:       callfoo:
154 ; CHECK-NEXT:    call void @foo(i32 1)
155 ; CHECK-NEXT:    br label [[EXIT]]
156 ; CHECK:       exit:
157 ; CHECK-NEXT:    ret i32 42
160 entry:
161   %cmp1 = icmp eq i32 %x, 4
162   %cmp2 = icmp slt i32 %x, 4
163   %select1 = select i1 %cmp2, i32 -1, i32 1
164   %select2 = select i1 %cmp1, i32 0, i32 %select1
165   %cond = icmp sgt i32 %select2, 0
166   br i1 %cond, label %callfoo, label %exit
168 callfoo:
169   call void @foo(i32 %select2)
170   br label %exit
172 exit:
173   ret i32 42
176 define i32 @compare_against_five(i32 %x) {
177 ; CHECK-LABEL: @compare_against_five(
178 ; CHECK-NEXT:  entry:
179 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 5
180 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
181 ; CHECK:       callfoo:
182 ; CHECK-NEXT:    call void @foo(i32 1)
183 ; CHECK-NEXT:    br label [[EXIT]]
184 ; CHECK:       exit:
185 ; CHECK-NEXT:    ret i32 42
188 entry:
189   %cmp1 = icmp eq i32 %x, 5
190   %cmp2 = icmp slt i32 %x, 5
191   %select1 = select i1 %cmp2, i32 -1, i32 1
192   %select2 = select i1 %cmp1, i32 0, i32 %select1
193   %cond = icmp sgt i32 %select2, 0
194   br i1 %cond, label %callfoo, label %exit
196 callfoo:
197   call void @foo(i32 %select2)
198   br label %exit
200 exit:
201   ret i32 42
204 define i32 @compare_against_six(i32 %x) {
205 ; CHECK-LABEL: @compare_against_six(
206 ; CHECK-NEXT:  entry:
207 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 6
208 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
209 ; CHECK:       callfoo:
210 ; CHECK-NEXT:    call void @foo(i32 1)
211 ; CHECK-NEXT:    br label [[EXIT]]
212 ; CHECK:       exit:
213 ; CHECK-NEXT:    ret i32 42
216 entry:
217   %cmp1 = icmp eq i32 %x, 6
218   %cmp2 = icmp slt i32 %x, 6
219   %select1 = select i1 %cmp2, i32 -1, i32 1
220   %select2 = select i1 %cmp1, i32 0, i32 %select1
221   %cond = icmp sgt i32 %select2, 0
222   br i1 %cond, label %callfoo, label %exit
224 callfoo:
225   call void @foo(i32 %select2)
226   br label %exit
228 exit:
229   ret i32 42
232 ; Same as @compare_against_arbitrary_value, but now the three-way comparison
233 ; returns not idiomatic comparator's result (-1, 0, 1) but some other constants.
234 define i32 @compare_against_arbitrary_value_non_idiomatic_1(i32 %x, i32 %c) {
235 ; CHECK-LABEL: @compare_against_arbitrary_value_non_idiomatic_1(
236 ; CHECK-NEXT:  entry:
237 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], [[C:%.*]]
238 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
239 ; CHECK:       callfoo:
240 ; CHECK-NEXT:    call void @foo(i32 425)
241 ; CHECK-NEXT:    br label [[EXIT]]
242 ; CHECK:       exit:
243 ; CHECK-NEXT:    ret i32 42
246 entry:
247   %cmp1 = icmp eq i32 %x, %c
248   %cmp2 = icmp slt i32 %x, %c
249   %select1 = select i1 %cmp2, i32 -6, i32 425
250   %select2 = select i1 %cmp1, i32 0, i32 %select1
251   %cond = icmp sgt i32 %select2, 0
252   br i1 %cond, label %callfoo, label %exit
254 callfoo:
255   call void @foo(i32 %select2)
256   br label %exit
258 exit:
259   ret i32 42
262 define i32 @compare_against_zero_non_idiomatic_add(i32 %x) {
263 ; CHECK-LABEL: @compare_against_zero_non_idiomatic_add(
264 ; CHECK-NEXT:  entry:
265 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 0
266 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
267 ; CHECK:       callfoo:
268 ; CHECK-NEXT:    call void @foo(i32 425)
269 ; CHECK-NEXT:    br label [[EXIT]]
270 ; CHECK:       exit:
271 ; CHECK-NEXT:    ret i32 42
274 entry:
275   %cmp1 = icmp eq i32 %x, 0
276   %cmp2 = icmp slt i32 %x, 0
277   %select1 = select i1 %cmp2, i32 -6, i32 425
278   %select2 = select i1 %cmp1, i32 0, i32 %select1
279   %cond = icmp sgt i32 %select2, 0
280   br i1 %cond, label %callfoo, label %exit
282 callfoo:
283   call void @foo(i32 %select2)
284   br label %exit
286 exit:
287   ret i32 42
290 ; Same as @compare_against_arbitrary_value, but now the three-way comparison
291 ; returns not idiomatic comparator's result (-1, 0, 1) but some other constants.
292 define i32 @compare_against_arbitrary_value_non_idiomatic_2(i32 %x, i32 %c) {
293 ; CHECK-LABEL: @compare_against_arbitrary_value_non_idiomatic_2(
294 ; CHECK-NEXT:  entry:
295 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], [[C:%.*]]
296 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
297 ; CHECK:       callfoo:
298 ; CHECK-NEXT:    call void @foo(i32 425)
299 ; CHECK-NEXT:    br label [[EXIT]]
300 ; CHECK:       exit:
301 ; CHECK-NEXT:    ret i32 42
304 entry:
305   %cmp1 = icmp eq i32 %x, %c
306   %cmp2 = icmp slt i32 %x, %c
307   %select1 = select i1 %cmp2, i32 -5, i32 425
308   %select2 = select i1 %cmp1, i32 0, i32 %select1
309   %cond = icmp sgt i32 %select2, 0
310   br i1 %cond, label %callfoo, label %exit
312 callfoo:
313   call void @foo(i32 %select2)
314   br label %exit
316 exit:
317   ret i32 42
320 define i32 @compare_against_zero_non_idiomatic_or(i32 %x) {
321 ; CHECK-LABEL: @compare_against_zero_non_idiomatic_or(
322 ; CHECK-NEXT:  entry:
323 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 0
324 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
325 ; CHECK:       callfoo:
326 ; CHECK-NEXT:    call void @foo(i32 425)
327 ; CHECK-NEXT:    br label [[EXIT]]
328 ; CHECK:       exit:
329 ; CHECK-NEXT:    ret i32 42
332 entry:
333   %cmp1 = icmp eq i32 %x, 0
334   %cmp2 = icmp slt i32 %x, 0
335   %select1 = select i1 %cmp2, i32 -5, i32 425
336   %select2 = select i1 %cmp1, i32 0, i32 %select1
337   %cond = icmp sgt i32 %select2, 0
338   br i1 %cond, label %callfoo, label %exit
340 callfoo:
341   call void @foo(i32 %select2)
342   br label %exit
344 exit:
345   ret i32 42
348 define i32 @compare_against_arbitrary_value_type_mismatch(i64 %x, i64 %c) {
349 ; CHECK-LABEL: @compare_against_arbitrary_value_type_mismatch(
350 ; CHECK-NEXT:  entry:
351 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i64 [[X:%.*]], [[C:%.*]]
352 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
353 ; CHECK:       callfoo:
354 ; CHECK-NEXT:    call void @foo(i32 1)
355 ; CHECK-NEXT:    br label [[EXIT]]
356 ; CHECK:       exit:
357 ; CHECK-NEXT:    ret i32 42
360 entry:
361   %cmp1 = icmp eq i64 %x, %c
362   %cmp2 = icmp slt i64 %x, %c
363   %select1 = select i1 %cmp2, i32 -1, i32 1
364   %select2 = select i1 %cmp1, i32 0, i32 %select1
365   %cond = icmp sgt i32 %select2, 0
366   br i1 %cond, label %callfoo, label %exit
368 callfoo:
369   call void @foo(i32 %select2)
370   br label %exit
372 exit:
373   ret i32 42
376 define i32 @compare_against_zero_type_mismatch_idiomatic(i64 %x) {
377 ; CHECK-LABEL: @compare_against_zero_type_mismatch_idiomatic(
378 ; CHECK-NEXT:  entry:
379 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i64 [[X:%.*]], 0
380 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
381 ; CHECK:       callfoo:
382 ; CHECK-NEXT:    call void @foo(i32 1)
383 ; CHECK-NEXT:    br label [[EXIT]]
384 ; CHECK:       exit:
385 ; CHECK-NEXT:    ret i32 42
388 entry:
389   %cmp1 = icmp eq i64 %x, 0
390   %cmp2 = icmp slt i64 %x, 0
391   %select1 = select i1 %cmp2, i32 -1, i32 1
392   %select2 = select i1 %cmp1, i32 0, i32 %select1
393   %cond = icmp sgt i32 %select2, 0
394   br i1 %cond, label %callfoo, label %exit
396 callfoo:
397   call void @foo(i32 %select2)
398   br label %exit
400 exit:
401   ret i32 42
404 define i32 @compare_against_zero_type_mismatch_non_idiomatic_1(i64 %x) {
405 ; CHECK-LABEL: @compare_against_zero_type_mismatch_non_idiomatic_1(
406 ; CHECK-NEXT:  entry:
407 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i64 [[X:%.*]], 0
408 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
409 ; CHECK:       callfoo:
410 ; CHECK-NEXT:    call void @foo(i32 1)
411 ; CHECK-NEXT:    br label [[EXIT]]
412 ; CHECK:       exit:
413 ; CHECK-NEXT:    ret i32 42
416 entry:
417   %cmp1 = icmp eq i64 %x, 0
418   %cmp2 = icmp slt i64 %x, 0
419   %select1 = select i1 %cmp2, i32 -7, i32 1
420   %select2 = select i1 %cmp1, i32 0, i32 %select1
421   %cond = icmp sgt i32 %select2, 0
422   br i1 %cond, label %callfoo, label %exit
424 callfoo:
425   call void @foo(i32 %select2)
426   br label %exit
428 exit:
429   ret i32 42
432 define i32 @compare_against_zero_type_mismatch_non_idiomatic_2(i64 %x) {
433 ; CHECK-LABEL: @compare_against_zero_type_mismatch_non_idiomatic_2(
434 ; CHECK-NEXT:  entry:
435 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i64 [[X:%.*]], 0
436 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
437 ; CHECK:       callfoo:
438 ; CHECK-NEXT:    call void @foo(i32 1)
439 ; CHECK-NEXT:    br label [[EXIT]]
440 ; CHECK:       exit:
441 ; CHECK-NEXT:    ret i32 42
444 entry:
445   %cmp1 = icmp eq i64 %x, 0
446   %cmp2 = icmp slt i64 %x, 0
447   %select1 = select i1 %cmp2, i32 -6, i32 1
448   %select2 = select i1 %cmp1, i32 0, i32 %select1
449   %cond = icmp sgt i32 %select2, 0
450   br i1 %cond, label %callfoo, label %exit
452 callfoo:
453   call void @foo(i32 %select2)
454   br label %exit
456 exit:
457   ret i32 42
460 declare void @use1(i1)
461 define i32 @compare_against_fortytwo_commutatibility_0(i32 %x) {
462 ; CHECK-LABEL: @compare_against_fortytwo_commutatibility_0(
463 ; CHECK-NEXT:  entry:
464 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 42
465 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
466 ; CHECK:       callfoo:
467 ; CHECK-NEXT:    call void @foo(i32 1)
468 ; CHECK-NEXT:    br label [[EXIT]]
469 ; CHECK:       exit:
470 ; CHECK-NEXT:    ret i32 84
472 entry:
473   %cmp1 = icmp eq i32 %x, 42
474   %cmp2 = icmp slt i32 %x, 42
475   %select1 = select i1 %cmp2, i32 -1, i32 1
476   %select2 = select i1 %cmp1, i32 0, i32 %select1
477   %cond = icmp sgt i32 %select2, 0
478   br i1 %cond, label %callfoo, label %exit
480 callfoo:
481   call void @foo(i32 %select2)
482   br label %exit
484 exit:
485   ret i32 84
487 define i32 @compare_against_fortytwo_commutatibility_1(i32 %x) {
488 ; CHECK-LABEL: @compare_against_fortytwo_commutatibility_1(
489 ; CHECK-NEXT:  entry:
490 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[X:%.*]], 42
491 ; CHECK-NEXT:    call void @use1(i1 [[CMP1]])
492 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X]], 42
493 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
494 ; CHECK:       callfoo:
495 ; CHECK-NEXT:    call void @foo(i32 1)
496 ; CHECK-NEXT:    br label [[EXIT]]
497 ; CHECK:       exit:
498 ; CHECK-NEXT:    ret i32 84
500 entry:
501   %cmp1 = icmp ne i32 %x, 42 ; inverted
502   call void @use1(i1 %cmp1)
503   %cmp2 = icmp slt i32 %x, 42
504   %select1 = select i1 %cmp2, i32 -1, i32 1
505   %select2 = select i1 %cmp1, i32 %select1, i32 0 ; swapped
506   %cond = icmp sgt i32 %select2, 0
507   br i1 %cond, label %callfoo, label %exit
509 callfoo:
510   call void @foo(i32 %select2)
511   br label %exit
513 exit:
514   ret i32 84
516 define i32 @compare_against_fortytwo_commutatibility_2(i32 %x) {
517 ; CHECK-LABEL: @compare_against_fortytwo_commutatibility_2(
518 ; CHECK-NEXT:  entry:
519 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 42
520 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
521 ; CHECK:       callfoo:
522 ; CHECK-NEXT:    call void @foo(i32 1)
523 ; CHECK-NEXT:    br label [[EXIT]]
524 ; CHECK:       exit:
525 ; CHECK-NEXT:    ret i32 84
527 entry:
528   %cmp1 = icmp eq i32 %x, 42
529   %cmp2 = icmp sgt i32 %x, 41 ; inverted
530   %select1 = select i1 %cmp2, i32 1, i32 -1 ; swapped
531   %select2 = select i1 %cmp1, i32 0, i32 %select1
532   %cond = icmp sgt i32 %select2, 0
533   br i1 %cond, label %callfoo, label %exit
535 callfoo:
536   call void @foo(i32 %select2)
537   br label %exit
539 exit:
540   ret i32 84
542 define i32 @compare_against_fortytwo_commutatibility_3(i32 %x) {
543 ; CHECK-LABEL: @compare_against_fortytwo_commutatibility_3(
544 ; CHECK-NEXT:  entry:
545 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[X:%.*]], 42
546 ; CHECK-NEXT:    call void @use1(i1 [[CMP1]])
547 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X]], 42
548 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
549 ; CHECK:       callfoo:
550 ; CHECK-NEXT:    call void @foo(i32 1)
551 ; CHECK-NEXT:    br label [[EXIT]]
552 ; CHECK:       exit:
553 ; CHECK-NEXT:    ret i32 84
555 entry:
556   %cmp1 = icmp ne i32 %x, 42 ; inverted
557   call void @use1(i1 %cmp1)
558   %cmp2 = icmp sgt i32 %x, 41 ; inverted
559   %select1 = select i1 %cmp2, i32 1, i32 -1 ; swapped
560   %select2 = select i1 %cmp1, i32 %select1, i32 0 ; swapped
561   %cond = icmp sgt i32 %select2, 0
562   br i1 %cond, label %callfoo, label %exit
564 callfoo:
565   call void @foo(i32 %select2)
566   br label %exit
568 exit:
569   ret i32 84
572 define i32 @compare_against_arbitrary_value_commutativity0(i32 %x, i32 %c) {
573 ; CHECK-LABEL: @compare_against_arbitrary_value_commutativity0(
574 ; CHECK-NEXT:  entry:
575 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], [[C:%.*]]
576 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
577 ; CHECK:       callfoo:
578 ; CHECK-NEXT:    call void @foo(i32 1)
579 ; CHECK-NEXT:    br label [[EXIT]]
580 ; CHECK:       exit:
581 ; CHECK-NEXT:    ret i32 42
583 entry:
584   %cmp1 = icmp eq i32 %x, %c
585   %cmp2 = icmp slt i32 %x, %c
586   %select1 = select i1 %cmp2, i32 -1, i32 1
587   %select2 = select i1 %cmp1, i32 0, i32 %select1
588   %cond = icmp sgt i32 %select2, 0
589   br i1 %cond, label %callfoo, label %exit
591 callfoo:
592   call void @foo(i32 %select2)
593   br label %exit
595 exit:
596   ret i32 42
598 define i32 @compare_against_arbitrary_value_commutativity1(i32 %x, i32 %c) {
599 ; CHECK-LABEL: @compare_against_arbitrary_value_commutativity1(
600 ; CHECK-NEXT:  entry:
601 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], [[C:%.*]]
602 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
603 ; CHECK:       callfoo:
604 ; CHECK-NEXT:    call void @foo(i32 1)
605 ; CHECK-NEXT:    br label [[EXIT]]
606 ; CHECK:       exit:
607 ; CHECK-NEXT:    ret i32 42
609 entry:
610   %cmp1 = icmp eq i32 %x, %c
611   %cmp2 = icmp sgt i32 %c, %x ; swapped
612   %select1 = select i1 %cmp2, i32 -1, i32 1
613   %select2 = select i1 %cmp1, i32 0, i32 %select1
614   %cond = icmp sgt i32 %select2, 0
615   br i1 %cond, label %callfoo, label %exit
617 callfoo:
618   call void @foo(i32 %select2)
619   br label %exit
621 exit:
622   ret i32 42
624 define i32 @compare_against_arbitrary_value_commutativity2(i32 %x, i32 %c) {
625 ; CHECK-LABEL: @compare_against_arbitrary_value_commutativity2(
626 ; CHECK-NEXT:  entry:
627 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[X:%.*]], [[C:%.*]]
628 ; CHECK-NEXT:    call void @use1(i1 [[CMP1]])
629 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X]], [[C]]
630 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
631 ; CHECK:       callfoo:
632 ; CHECK-NEXT:    call void @foo(i32 1)
633 ; CHECK-NEXT:    br label [[EXIT]]
634 ; CHECK:       exit:
635 ; CHECK-NEXT:    ret i32 42
637 entry:
638   %cmp1 = icmp ne i32 %x, %c ; inverted
639   call void @use1(i1 %cmp1)
640   %cmp2 = icmp slt i32 %x, %c
641   %select1 = select i1 %cmp2, i32 -1, i32 1
642   %select2 = select i1 %cmp1, i32 %select1, i32 0 ; swapped
643   %cond = icmp sgt i32 %select2, 0
644   br i1 %cond, label %callfoo, label %exit
646 callfoo:
647   call void @foo(i32 %select2)
648   br label %exit
650 exit:
651   ret i32 42
653 define i32 @compare_against_arbitrary_value_commutativity3(i32 %x, i32 %c) {
654 ; CHECK-LABEL: @compare_against_arbitrary_value_commutativity3(
655 ; CHECK-NEXT:  entry:
656 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[X:%.*]], [[C:%.*]]
657 ; CHECK-NEXT:    call void @use1(i1 [[CMP1]])
658 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X]], [[C]]
659 ; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
660 ; CHECK:       callfoo:
661 ; CHECK-NEXT:    call void @foo(i32 1)
662 ; CHECK-NEXT:    br label [[EXIT]]
663 ; CHECK:       exit:
664 ; CHECK-NEXT:    ret i32 42
666 entry:
667   %cmp1 = icmp ne i32 %x, %c ; inverted
668   call void @use1(i1 %cmp1)
669   %cmp2 = icmp sgt i32 %c, %x ; swapped
670   %select1 = select i1 %cmp2, i32 -1, i32 1
671   %select2 = select i1 %cmp1, i32 %select1, i32 0 ; swapped
672   %cond = icmp sgt i32 %select2, 0
673   br i1 %cond, label %callfoo, label %exit
675 callfoo:
676   call void @foo(i32 %select2)
677   br label %exit
679 exit:
680   ret i32 42