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(
11 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], [[C:%.*]]
12 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
14 ; CHECK-NEXT: call void @foo(i32 1)
15 ; CHECK-NEXT: br label [[EXIT]]
17 ; CHECK-NEXT: ret i32 42
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
29 call void @foo(i32 %select2)
36 define i32 @compare_against_zero(i32 %x) {
37 ; CHECK-LABEL: @compare_against_zero(
39 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 0
40 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
42 ; CHECK-NEXT: call void @foo(i32 1)
43 ; CHECK-NEXT: br label [[EXIT]]
45 ; CHECK-NEXT: ret i32 42
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
57 call void @foo(i32 %select2)
64 define i32 @compare_against_one(i32 %x) {
65 ; CHECK-LABEL: @compare_against_one(
67 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 1
68 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
70 ; CHECK-NEXT: call void @foo(i32 1)
71 ; CHECK-NEXT: br label [[EXIT]]
73 ; CHECK-NEXT: ret i32 42
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
85 call void @foo(i32 %select2)
92 define i32 @compare_against_two(i32 %x) {
93 ; CHECK-LABEL: @compare_against_two(
95 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 2
96 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
98 ; CHECK-NEXT: call void @foo(i32 1)
99 ; CHECK-NEXT: br label [[EXIT]]
101 ; CHECK-NEXT: ret i32 42
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
113 call void @foo(i32 %select2)
120 define i32 @compare_against_three(i32 %x) {
121 ; CHECK-LABEL: @compare_against_three(
123 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 3
124 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
126 ; CHECK-NEXT: call void @foo(i32 1)
127 ; CHECK-NEXT: br label [[EXIT]]
129 ; CHECK-NEXT: ret i32 42
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
141 call void @foo(i32 %select2)
148 define i32 @compare_against_four(i32 %x) {
149 ; CHECK-LABEL: @compare_against_four(
151 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 4
152 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
154 ; CHECK-NEXT: call void @foo(i32 1)
155 ; CHECK-NEXT: br label [[EXIT]]
157 ; CHECK-NEXT: ret i32 42
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
169 call void @foo(i32 %select2)
176 define i32 @compare_against_five(i32 %x) {
177 ; CHECK-LABEL: @compare_against_five(
179 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 5
180 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
182 ; CHECK-NEXT: call void @foo(i32 1)
183 ; CHECK-NEXT: br label [[EXIT]]
185 ; CHECK-NEXT: ret i32 42
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
197 call void @foo(i32 %select2)
204 define i32 @compare_against_six(i32 %x) {
205 ; CHECK-LABEL: @compare_against_six(
207 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 6
208 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
210 ; CHECK-NEXT: call void @foo(i32 1)
211 ; CHECK-NEXT: br label [[EXIT]]
213 ; CHECK-NEXT: ret i32 42
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
225 call void @foo(i32 %select2)
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(
237 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], [[C:%.*]]
238 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
240 ; CHECK-NEXT: call void @foo(i32 425)
241 ; CHECK-NEXT: br label [[EXIT]]
243 ; CHECK-NEXT: ret i32 42
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
255 call void @foo(i32 %select2)
262 define i32 @compare_against_zero_non_idiomatic_add(i32 %x) {
263 ; CHECK-LABEL: @compare_against_zero_non_idiomatic_add(
265 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 0
266 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
268 ; CHECK-NEXT: call void @foo(i32 425)
269 ; CHECK-NEXT: br label [[EXIT]]
271 ; CHECK-NEXT: ret i32 42
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
283 call void @foo(i32 %select2)
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(
295 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], [[C:%.*]]
296 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
298 ; CHECK-NEXT: call void @foo(i32 425)
299 ; CHECK-NEXT: br label [[EXIT]]
301 ; CHECK-NEXT: ret i32 42
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
313 call void @foo(i32 %select2)
320 define i32 @compare_against_zero_non_idiomatic_or(i32 %x) {
321 ; CHECK-LABEL: @compare_against_zero_non_idiomatic_or(
323 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 0
324 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
326 ; CHECK-NEXT: call void @foo(i32 425)
327 ; CHECK-NEXT: br label [[EXIT]]
329 ; CHECK-NEXT: ret i32 42
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
341 call void @foo(i32 %select2)
348 define i32 @compare_against_arbitrary_value_type_mismatch(i64 %x, i64 %c) {
349 ; CHECK-LABEL: @compare_against_arbitrary_value_type_mismatch(
351 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i64 [[X:%.*]], [[C:%.*]]
352 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
354 ; CHECK-NEXT: call void @foo(i32 1)
355 ; CHECK-NEXT: br label [[EXIT]]
357 ; CHECK-NEXT: ret i32 42
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
369 call void @foo(i32 %select2)
376 define i32 @compare_against_zero_type_mismatch_idiomatic(i64 %x) {
377 ; CHECK-LABEL: @compare_against_zero_type_mismatch_idiomatic(
379 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i64 [[X:%.*]], 0
380 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
382 ; CHECK-NEXT: call void @foo(i32 1)
383 ; CHECK-NEXT: br label [[EXIT]]
385 ; CHECK-NEXT: ret i32 42
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
397 call void @foo(i32 %select2)
404 define i32 @compare_against_zero_type_mismatch_non_idiomatic_1(i64 %x) {
405 ; CHECK-LABEL: @compare_against_zero_type_mismatch_non_idiomatic_1(
407 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i64 [[X:%.*]], 0
408 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
410 ; CHECK-NEXT: call void @foo(i32 1)
411 ; CHECK-NEXT: br label [[EXIT]]
413 ; CHECK-NEXT: ret i32 42
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
425 call void @foo(i32 %select2)
432 define i32 @compare_against_zero_type_mismatch_non_idiomatic_2(i64 %x) {
433 ; CHECK-LABEL: @compare_against_zero_type_mismatch_non_idiomatic_2(
435 ; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i64 [[X:%.*]], 0
436 ; CHECK-NEXT: br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
438 ; CHECK-NEXT: call void @foo(i32 1)
439 ; CHECK-NEXT: br label [[EXIT]]
441 ; CHECK-NEXT: ret i32 42
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
453 call void @foo(i32 %select2)