1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
6 ; These 18 exercise all combinations of signed comparison
7 ; for each of the three values produced by your typical
8 ; 3way compare function (-1, 0, 1)
10 define void @test_low_sgt(i64 %a, i64 %b) {
11 ; CHECK-LABEL: define void @test_low_sgt
12 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
13 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp slt i64 [[A]], [[B]]
14 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[NORMAL:%.*]], label [[UNREACHED:%.*]]
16 ; CHECK-NEXT: ret void
18 ; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
19 ; CHECK-NEXT: call void @use(i32 [[RESULT]])
20 ; CHECK-NEXT: ret void
22 %eq = icmp eq i64 %a, %b
23 %slt = icmp slt i64 %a, %b
24 %. = select i1 %slt, i32 -1, i32 1
25 %result = select i1 %eq, i32 0, i32 %.
26 %cmp = icmp sgt i32 %result, -1
27 br i1 %cmp, label %unreached, label %normal
31 call void @use(i32 %result)
35 define void @test_low_slt(i64 %a, i64 %b) {
36 ; CHECK-LABEL: define void @test_low_slt
37 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
38 ; CHECK-NEXT: br i1 false, label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
40 ; CHECK-NEXT: ret void
42 ; CHECK-NEXT: ret void
44 %eq = icmp eq i64 %a, %b
45 %slt = icmp slt i64 %a, %b
46 %. = select i1 %slt, i32 -1, i32 1
47 %result = select i1 %eq, i32 0, i32 %.
48 %cmp = icmp slt i32 %result, -1
49 br i1 %cmp, label %unreached, label %normal
53 call void @use(i32 %result)
57 define void @test_low_sge(i64 %a, i64 %b) {
58 ; CHECK-LABEL: define void @test_low_sge
59 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
60 ; CHECK-NEXT: br i1 true, label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
62 ; CHECK-NEXT: ret void
64 ; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
65 ; CHECK-NEXT: call void @use(i32 [[RESULT]])
66 ; CHECK-NEXT: ret void
68 %eq = icmp eq i64 %a, %b
69 %slt = icmp slt i64 %a, %b
70 %. = select i1 %slt, i32 -1, i32 1
71 %result = select i1 %eq, i32 0, i32 %.
72 %cmp = icmp sge i32 %result, -1
73 br i1 %cmp, label %unreached, label %normal
77 call void @use(i32 %result)
81 define void @test_low_sle(i64 %a, i64 %b) {
82 ; CHECK-LABEL: define void @test_low_sle
83 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
84 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[A]], [[B]]
85 ; CHECK-NEXT: br i1 [[TMP1]], label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
87 ; CHECK-NEXT: ret void
89 ; CHECK-NEXT: call void @use(i32 -1)
90 ; CHECK-NEXT: ret void
92 %eq = icmp eq i64 %a, %b
93 %slt = icmp slt i64 %a, %b
94 %. = select i1 %slt, i32 -1, i32 1
95 %result = select i1 %eq, i32 0, i32 %.
96 %cmp = icmp sle i32 %result, -1
97 br i1 %cmp, label %unreached, label %normal
101 call void @use(i32 %result)
105 define void @test_low_ne(i64 %a, i64 %b) {
106 ; CHECK-LABEL: define void @test_low_ne
107 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
108 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[A]], [[B]]
109 ; CHECK-NEXT: br i1 [[TMP1]], label [[NORMAL:%.*]], label [[UNREACHED:%.*]]
111 ; CHECK-NEXT: ret void
113 ; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
114 ; CHECK-NEXT: call void @use(i32 [[RESULT]])
115 ; CHECK-NEXT: ret void
117 %eq = icmp eq i64 %a, %b
118 %slt = icmp slt i64 %a, %b
119 %. = select i1 %slt, i32 -1, i32 1
120 %result = select i1 %eq, i32 0, i32 %.
121 %cmp = icmp ne i32 %result, -1
122 br i1 %cmp, label %unreached, label %normal
126 call void @use(i32 %result)
130 define void @test_low_eq(i64 %a, i64 %b) {
131 ; CHECK-LABEL: define void @test_low_eq
132 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
133 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[A]], [[B]]
134 ; CHECK-NEXT: br i1 [[TMP1]], label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
136 ; CHECK-NEXT: ret void
138 ; CHECK-NEXT: call void @use(i32 -1)
139 ; CHECK-NEXT: ret void
141 %eq = icmp eq i64 %a, %b
142 %slt = icmp slt i64 %a, %b
143 %. = select i1 %slt, i32 -1, i32 1
144 %result = select i1 %eq, i32 0, i32 %.
145 %cmp = icmp eq i32 %result, -1
146 br i1 %cmp, label %unreached, label %normal
150 call void @use(i32 %result)
154 define void @test_mid_sgt(i64 %a, i64 %b) {
155 ; CHECK-LABEL: define void @test_mid_sgt
156 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
157 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[A]], [[B]]
158 ; CHECK-NEXT: br i1 [[TMP1]], label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
160 ; CHECK-NEXT: ret void
162 ; CHECK-NEXT: call void @use(i32 1)
163 ; CHECK-NEXT: ret void
165 %eq = icmp eq i64 %a, %b
166 %slt = icmp slt i64 %a, %b
167 %. = select i1 %slt, i32 -1, i32 1
168 %result = select i1 %eq, i32 0, i32 %.
169 %cmp = icmp sgt i32 %result, 0
170 br i1 %cmp, label %unreached, label %normal
174 call void @use(i32 %result)
178 define void @test_mid_slt(i64 %a, i64 %b) {
179 ; CHECK-LABEL: define void @test_mid_slt
180 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
181 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[A]], [[B]]
182 ; CHECK-NEXT: br i1 [[TMP1]], label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
184 ; CHECK-NEXT: ret void
186 ; CHECK-NEXT: call void @use(i32 -1)
187 ; CHECK-NEXT: ret void
189 %eq = icmp eq i64 %a, %b
190 %slt = icmp slt i64 %a, %b
191 %. = select i1 %slt, i32 -1, i32 1
192 %result = select i1 %eq, i32 0, i32 %.
193 %cmp = icmp slt i32 %result, 0
194 br i1 %cmp, label %unreached, label %normal
198 call void @use(i32 %result)
202 define void @test_mid_sge(i64 %a, i64 %b) {
203 ; CHECK-LABEL: define void @test_mid_sge
204 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
205 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp slt i64 [[A]], [[B]]
206 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[NORMAL:%.*]], label [[UNREACHED:%.*]]
208 ; CHECK-NEXT: ret void
210 ; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
211 ; CHECK-NEXT: call void @use(i32 [[RESULT]])
212 ; CHECK-NEXT: ret void
214 %eq = icmp eq i64 %a, %b
215 %slt = icmp slt i64 %a, %b
216 %. = select i1 %slt, i32 -1, i32 1
217 %result = select i1 %eq, i32 0, i32 %.
218 %cmp = icmp sge i32 %result, 0
219 br i1 %cmp, label %unreached, label %normal
223 call void @use(i32 %result)
227 define void @test_mid_sle(i64 %a, i64 %b) {
228 ; CHECK-LABEL: define void @test_mid_sle
229 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
230 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt i64 [[A]], [[B]]
231 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[NORMAL:%.*]], label [[UNREACHED:%.*]]
233 ; CHECK-NEXT: ret void
235 ; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
236 ; CHECK-NEXT: call void @use(i32 [[RESULT]])
237 ; CHECK-NEXT: ret void
239 %eq = icmp eq i64 %a, %b
240 %slt = icmp slt i64 %a, %b
241 %. = select i1 %slt, i32 -1, i32 1
242 %result = select i1 %eq, i32 0, i32 %.
243 %cmp = icmp sle i32 %result, 0
244 br i1 %cmp, label %unreached, label %normal
248 call void @use(i32 %result)
252 define void @test_mid_ne(i64 %a, i64 %b) {
253 ; CHECK-LABEL: define void @test_mid_ne
254 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
255 ; CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[A]], [[B]]
256 ; CHECK-NEXT: br i1 [[EQ]], label [[NORMAL:%.*]], label [[UNREACHED:%.*]]
258 ; CHECK-NEXT: ret void
260 ; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
261 ; CHECK-NEXT: call void @use(i32 [[RESULT]])
262 ; CHECK-NEXT: ret void
264 %eq = icmp eq i64 %a, %b
265 %slt = icmp slt i64 %a, %b
266 %. = select i1 %slt, i32 -1, i32 1
267 %result = select i1 %eq, i32 0, i32 %.
268 %cmp = icmp ne i32 %result, 0
269 br i1 %cmp, label %unreached, label %normal
273 call void @use(i32 %result)
277 define void @test_mid_eq(i64 %a, i64 %b) {
278 ; CHECK-LABEL: define void @test_mid_eq
279 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
280 ; CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[A]], [[B]]
281 ; CHECK-NEXT: br i1 [[EQ]], label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
283 ; CHECK-NEXT: ret void
285 ; CHECK-NEXT: call void @use(i32 0)
286 ; CHECK-NEXT: ret void
288 %eq = icmp eq i64 %a, %b
289 %slt = icmp slt i64 %a, %b
290 %. = select i1 %slt, i32 -1, i32 1
291 %result = select i1 %eq, i32 0, i32 %.
292 %cmp = icmp eq i32 %result, 0
293 br i1 %cmp, label %unreached, label %normal
297 call void @use(i32 %result)
301 define void @test_high_sgt(i64 %a, i64 %b) {
302 ; CHECK-LABEL: define void @test_high_sgt
303 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
304 ; CHECK-NEXT: br i1 false, label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
306 ; CHECK-NEXT: ret void
308 ; CHECK-NEXT: ret void
310 %eq = icmp eq i64 %a, %b
311 %slt = icmp slt i64 %a, %b
312 %. = select i1 %slt, i32 -1, i32 1
313 %result = select i1 %eq, i32 0, i32 %.
314 %cmp = icmp sgt i32 %result, 1
315 br i1 %cmp, label %unreached, label %normal
319 call void @use(i32 %result)
323 define void @test_high_slt(i64 %a, i64 %b) {
324 ; CHECK-LABEL: define void @test_high_slt
325 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
326 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt i64 [[A]], [[B]]
327 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[NORMAL:%.*]], label [[UNREACHED:%.*]]
329 ; CHECK-NEXT: ret void
331 ; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
332 ; CHECK-NEXT: call void @use(i32 [[RESULT]])
333 ; CHECK-NEXT: ret void
335 %eq = icmp eq i64 %a, %b
336 %slt = icmp slt i64 %a, %b
337 %. = select i1 %slt, i32 -1, i32 1
338 %result = select i1 %eq, i32 0, i32 %.
339 %cmp = icmp slt i32 %result, 1
340 br i1 %cmp, label %unreached, label %normal
344 call void @use(i32 %result)
348 define void @test_high_sge(i64 %a, i64 %b) {
349 ; CHECK-LABEL: define void @test_high_sge
350 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
351 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[A]], [[B]]
352 ; CHECK-NEXT: br i1 [[TMP1]], label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
354 ; CHECK-NEXT: ret void
356 ; CHECK-NEXT: call void @use(i32 1)
357 ; CHECK-NEXT: ret void
359 %eq = icmp eq i64 %a, %b
360 %slt = icmp slt i64 %a, %b
361 %. = select i1 %slt, i32 -1, i32 1
362 %result = select i1 %eq, i32 0, i32 %.
363 %cmp = icmp sge i32 %result, 1
364 br i1 %cmp, label %unreached, label %normal
368 call void @use(i32 %result)
372 define void @test_high_sle(i64 %a, i64 %b) {
373 ; CHECK-LABEL: define void @test_high_sle
374 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
375 ; CHECK-NEXT: br i1 true, label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
377 ; CHECK-NEXT: ret void
379 ; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
380 ; CHECK-NEXT: call void @use(i32 [[RESULT]])
381 ; CHECK-NEXT: ret void
383 %eq = icmp eq i64 %a, %b
384 %slt = icmp slt i64 %a, %b
385 %. = select i1 %slt, i32 -1, i32 1
386 %result = select i1 %eq, i32 0, i32 %.
387 %cmp = icmp sle i32 %result, 1
388 br i1 %cmp, label %unreached, label %normal
392 call void @use(i32 %result)
396 define void @test_high_ne(i64 %a, i64 %b) {
397 ; CHECK-LABEL: define void @test_high_ne
398 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
399 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[A]], [[B]]
400 ; CHECK-NEXT: br i1 [[TMP1]], label [[NORMAL:%.*]], label [[UNREACHED:%.*]]
402 ; CHECK-NEXT: ret void
404 ; CHECK-NEXT: [[RESULT:%.*]] = call i32 @llvm.scmp.i32.i64(i64 [[A]], i64 [[B]])
405 ; CHECK-NEXT: call void @use(i32 [[RESULT]])
406 ; CHECK-NEXT: ret void
408 %eq = icmp eq i64 %a, %b
409 %slt = icmp slt i64 %a, %b
410 %. = select i1 %slt, i32 -1, i32 1
411 %result = select i1 %eq, i32 0, i32 %.
412 %cmp = icmp ne i32 %result, 1
413 br i1 %cmp, label %unreached, label %normal
417 call void @use(i32 %result)
421 define void @test_high_eq(i64 %a, i64 %b) {
422 ; CHECK-LABEL: define void @test_high_eq
423 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
424 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[A]], [[B]]
425 ; CHECK-NEXT: br i1 [[TMP1]], label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
427 ; CHECK-NEXT: ret void
429 ; CHECK-NEXT: call void @use(i32 1)
430 ; CHECK-NEXT: ret void
432 %eq = icmp eq i64 %a, %b
433 %slt = icmp slt i64 %a, %b
434 %. = select i1 %slt, i32 -1, i32 1
435 %result = select i1 %eq, i32 0, i32 %.
436 %cmp = icmp eq i32 %result, 1
437 br i1 %cmp, label %unreached, label %normal
441 call void @use(i32 %result)
445 ; These five make sure we didn't accidentally hard code one of the
448 define void @non_standard_low(i64 %a, i64 %b) {
449 ; CHECK-LABEL: define void @non_standard_low
450 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
451 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i64 [[A]], [[B]]
452 ; CHECK-NEXT: br i1 [[TMP1]], label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
454 ; CHECK-NEXT: ret void
456 ; CHECK-NEXT: call void @use(i32 -3)
457 ; CHECK-NEXT: ret void
459 %eq = icmp eq i64 %a, %b
460 %slt = icmp slt i64 %a, %b
461 %. = select i1 %slt, i32 -3, i32 -1
462 %result = select i1 %eq, i32 -2, i32 %.
463 %cmp = icmp eq i32 %result, -3
464 br i1 %cmp, label %unreached, label %normal
468 call void @use(i32 %result)
472 define void @non_standard_mid(i64 %a, i64 %b) {
473 ; CHECK-LABEL: define void @non_standard_mid
474 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
475 ; CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[A]], [[B]]
476 ; CHECK-NEXT: br i1 [[EQ]], label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
478 ; CHECK-NEXT: ret void
480 ; CHECK-NEXT: call void @use(i32 -2)
481 ; CHECK-NEXT: ret void
483 %eq = icmp eq i64 %a, %b
484 %slt = icmp slt i64 %a, %b
485 %. = select i1 %slt, i32 -3, i32 -1
486 %result = select i1 %eq, i32 -2, i32 %.
487 %cmp = icmp eq i32 %result, -2
488 br i1 %cmp, label %unreached, label %normal
492 call void @use(i32 %result)
496 define void @non_standard_high(i64 %a, i64 %b) {
497 ; CHECK-LABEL: define void @non_standard_high
498 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
499 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i64 [[A]], [[B]]
500 ; CHECK-NEXT: br i1 [[TMP1]], label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
502 ; CHECK-NEXT: ret void
504 ; CHECK-NEXT: call void @use(i32 -1)
505 ; CHECK-NEXT: ret void
507 %eq = icmp eq i64 %a, %b
508 %slt = icmp slt i64 %a, %b
509 %. = select i1 %slt, i32 -3, i32 -1
510 %result = select i1 %eq, i32 -2, i32 %.
511 %cmp = icmp eq i32 %result, -1
512 br i1 %cmp, label %unreached, label %normal
516 call void @use(i32 %result)
520 define void @non_standard_bound1(i64 %a, i64 %b) {
521 ; CHECK-LABEL: define void @non_standard_bound1
522 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
523 ; CHECK-NEXT: br i1 false, label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
525 ; CHECK-NEXT: ret void
527 ; CHECK-NEXT: ret void
529 %eq = icmp eq i64 %a, %b
530 %slt = icmp slt i64 %a, %b
531 %. = select i1 %slt, i32 -3, i32 -1
532 %result = select i1 %eq, i32 -2, i32 %.
533 %cmp = icmp eq i32 %result, -20
534 br i1 %cmp, label %unreached, label %normal
538 call void @use(i32 %result)
542 define void @non_standard_bound2(i64 %a, i64 %b) {
543 ; CHECK-LABEL: define void @non_standard_bound2
544 ; CHECK-SAME: (i64 [[A:%.*]], i64 [[B:%.*]]) {
545 ; CHECK-NEXT: br i1 false, label [[UNREACHED:%.*]], label [[NORMAL:%.*]]
547 ; CHECK-NEXT: ret void
549 ; CHECK-NEXT: ret void
551 %eq = icmp eq i64 %a, %b
552 %slt = icmp slt i64 %a, %b
553 %. = select i1 %slt, i32 -3, i32 -1
554 %result = select i1 %eq, i32 -2, i32 %.
555 %cmp = icmp eq i32 %result, 0
556 br i1 %cmp, label %unreached, label %normal
560 call void @use(i32 %result)