[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / InstCombine / unrecognized_three-way-comparison.ll
blobdcd046e6760267d520199a8d45aba8b86a8bef16
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