1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
4 define void @test_shl(i1 %x) {
5 ; CHECK-LABEL: @test_shl(
6 ; CHECK-NEXT: call void @sink(i8 0)
12 call void @sink(i8 %a)
16 define void @test_lshr(i1 %x) {
17 ; CHECK-LABEL: @test_lshr(
18 ; CHECK-NEXT: call void @sink(i8 0)
19 ; CHECK-NEXT: ret void
24 call void @sink(i8 %a)
28 define void @test_ashr(i1 %x) {
29 ; CHECK-LABEL: @test_ashr(
30 ; CHECK-NEXT: call void @sink(i8 0)
31 ; CHECK-NEXT: ret void
36 call void @sink(i8 %a)
40 define void @test_udiv(i8 %x) {
41 ; CHECK-LABEL: @test_udiv(
42 ; CHECK-NEXT: call void @sink(i8 0)
43 ; CHECK-NEXT: ret void
47 call void @sink(i8 %z)
51 define i8 @test_cond(i8 %x) {
52 ; CHECK-LABEL: @test_cond(
53 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
54 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0
55 ; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[EXIT:%.*]]
57 ; CHECK-NEXT: ret i8 -4
59 ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
60 ; CHECK-NEXT: ret i8 [[OR2]]
63 %cmp = icmp eq i8 %and, 0
64 br i1 %cmp, label %if, label %exit
75 define i8 @test_cond_inv(i8 %x) {
76 ; CHECK-LABEL: @test_cond_inv(
77 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
78 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0
79 ; CHECK-NEXT: call void @use(i1 [[CMP]])
80 ; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[IF:%.*]]
82 ; CHECK-NEXT: ret i8 -4
84 ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
85 ; CHECK-NEXT: ret i8 [[OR2]]
88 %cmp = icmp ne i8 %and, 0
89 call void @use(i1 %cmp)
90 br i1 %cmp, label %exit, label %if
101 define i8 @test_cond_and(i8 %x, i1 %c) {
102 ; CHECK-LABEL: @test_cond_and(
103 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
104 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0
105 ; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP]], [[C:%.*]]
106 ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
108 ; CHECK-NEXT: ret i8 -4
110 ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
111 ; CHECK-NEXT: ret i8 [[OR2]]
114 %cmp = icmp eq i8 %and, 0
115 %cond = and i1 %cmp, %c
116 br i1 %cond, label %if, label %exit
127 define i8 @test_cond_and_bothways(i8 %x) {
128 ; CHECK-LABEL: @test_cond_and_bothways(
129 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 91
130 ; CHECK-NEXT: [[CMP0:%.*]] = icmp ne i8 [[AND]], 24
131 ; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[X]], 0
132 ; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP0]], [[CMP1]]
133 ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
135 ; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
136 ; CHECK-NEXT: ret i8 [[OR1]]
138 ; CHECK-NEXT: ret i8 -4
141 %cmp0 = icmp ne i8 %and, 24
142 %cmp1 = icmp ne i8 %x, 0
143 %cond = and i1 %cmp0, %cmp1
144 br i1 %cond, label %if, label %exit
155 define i8 @test_cond_or_bothways(i8 %x) {
156 ; CHECK-LABEL: @test_cond_or_bothways(
157 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 91
158 ; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i8 [[AND]], 24
159 ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X]], 0
160 ; CHECK-NEXT: [[COND:%.*]] = or i1 [[CMP0]], [[CMP1]]
161 ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
163 ; CHECK-NEXT: ret i8 -4
165 ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
166 ; CHECK-NEXT: ret i8 [[OR2]]
169 %cmp0 = icmp eq i8 %and, 24
170 %cmp1 = icmp eq i8 %x, 0
171 %cond = or i1 %cmp0, %cmp1
172 br i1 %cond, label %if, label %exit
183 define i8 @test_cond_and_commuted(i8 %x, i1 %c1, i1 %c2) {
184 ; CHECK-LABEL: @test_cond_and_commuted(
185 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
186 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0
187 ; CHECK-NEXT: [[C3:%.*]] = and i1 [[C1:%.*]], [[C2:%.*]]
188 ; CHECK-NEXT: [[COND:%.*]] = and i1 [[C3]], [[CMP]]
189 ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
191 ; CHECK-NEXT: ret i8 -4
193 ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
194 ; CHECK-NEXT: ret i8 [[OR2]]
197 %cmp = icmp eq i8 %and, 0
198 %c3 = and i1 %c1, %c2
199 %cond = and i1 %c3, %cmp
200 br i1 %cond, label %if, label %exit
211 define i8 @test_cond_logical_and(i8 %x, i1 %c) {
212 ; CHECK-LABEL: @test_cond_logical_and(
213 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
214 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0
215 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i1 [[C:%.*]], i1 false
216 ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
218 ; CHECK-NEXT: ret i8 -4
220 ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
221 ; CHECK-NEXT: ret i8 [[OR2]]
224 %cmp = icmp eq i8 %and, 0
225 %cond = select i1 %cmp, i1 %c, i1 false
226 br i1 %cond, label %if, label %exit
237 define i8 @test_cond_or_invalid(i8 %x, i1 %c) {
238 ; CHECK-LABEL: @test_cond_or_invalid(
239 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
240 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0
241 ; CHECK-NEXT: [[COND:%.*]] = or i1 [[CMP]], [[C:%.*]]
242 ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
244 ; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
245 ; CHECK-NEXT: ret i8 [[OR1]]
247 ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
248 ; CHECK-NEXT: ret i8 [[OR2]]
251 %cmp = icmp eq i8 %and, 0
252 %cond = or i1 %cmp, %c
253 br i1 %cond, label %if, label %exit
264 define i8 @test_cond_inv_or(i8 %x, i1 %c) {
265 ; CHECK-LABEL: @test_cond_inv_or(
266 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
267 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0
268 ; CHECK-NEXT: [[COND:%.*]] = or i1 [[CMP]], [[C:%.*]]
269 ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
271 ; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
272 ; CHECK-NEXT: ret i8 [[OR1]]
274 ; CHECK-NEXT: ret i8 -4
277 %cmp = icmp ne i8 %and, 0
278 %cond = or i1 %cmp, %c
279 br i1 %cond, label %if, label %exit
290 define i8 @test_cond_inv_logical_or(i8 %x, i1 %c) {
291 ; CHECK-LABEL: @test_cond_inv_logical_or(
292 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
293 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[AND]], 0
294 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP_NOT]], i1 [[C:%.*]], i1 false
295 ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
297 ; CHECK-NEXT: ret i8 -4
299 ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
300 ; CHECK-NEXT: ret i8 [[OR2]]
303 %cmp = icmp ne i8 %and, 0
304 %cond = select i1 %cmp, i1 false, i1 %c
305 br i1 %cond, label %if, label %exit
316 define i8 @test_cond_inv_and_invalid(i8 %x, i1 %c) {
317 ; CHECK-LABEL: @test_cond_inv_and_invalid(
318 ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 3
319 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[AND]], 0
320 ; CHECK-NEXT: [[COND:%.*]] = and i1 [[CMP]], [[C:%.*]]
321 ; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
323 ; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -4
324 ; CHECK-NEXT: ret i8 [[OR1]]
326 ; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -4
327 ; CHECK-NEXT: ret i8 [[OR2]]
330 %cmp = icmp ne i8 %and, 0
331 %cond = and i1 %cmp, %c
332 br i1 %cond, label %if, label %exit
343 define i32 @test_icmp_trunc1(i32 %x) {
344 ; CHECK-LABEL: @test_icmp_trunc1(
346 ; CHECK-NEXT: [[Y:%.*]] = trunc i32 [[X:%.*]] to i16
347 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[Y]], 7
348 ; CHECK-NEXT: br i1 [[CMP]], label [[THEN:%.*]], label [[ELSE:%.*]]
350 ; CHECK-NEXT: ret i32 7
352 ; CHECK-NEXT: ret i32 0
355 %y = trunc i32 %x to i16
356 %cmp = icmp eq i16 %y, 7
357 br i1 %cmp, label %then, label %else
365 define i32 @test_icmp_trunc_assume(i32 %x) {
366 ; CHECK-LABEL: @test_icmp_trunc_assume(
368 ; CHECK-NEXT: [[Y:%.*]] = trunc i32 [[X:%.*]] to i16
369 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[Y]], 7
370 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
371 ; CHECK-NEXT: ret i32 7
374 %y = trunc i32 %x to i16
375 %cmp = icmp eq i16 %y, 7
376 call void @llvm.assume(i1 %cmp)
381 define i64 @test_icmp_trunc2(i64 %x) {
382 ; CHECK-LABEL: @test_icmp_trunc2(
383 ; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[X:%.*]] to i32
384 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CONV]], 12
385 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
387 ; CHECK-NEXT: [[SEXT:%.*]] = and i64 [[X]], 2147483647
388 ; CHECK-NEXT: ret i64 [[SEXT]]
390 ; CHECK-NEXT: ret i64 0
392 %conv = trunc i64 %x to i32
393 %cmp = icmp sgt i32 %conv, 12
394 br i1 %cmp, label %if.then, label %if.else
397 %sext = shl i64 %x, 32
398 %ret = ashr exact i64 %sext, 32
404 define i64 @test_icmp_trunc3(i64 %n) {
405 ; CHECK-LABEL: @test_icmp_trunc3(
407 ; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[N:%.*]] to i32
408 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[CONV]], 96
409 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
411 ; CHECK-NEXT: [[RET:%.*]] = and i64 [[N]], 127
412 ; CHECK-NEXT: ret i64 [[RET]]
414 ; CHECK-NEXT: ret i64 0
417 %conv = trunc i64 %n to i32
418 %cmp = icmp ult i32 %conv, 96
419 br i1 %cmp, label %if.then, label %if.else
422 %ret = and i64 %n, 4294967295
429 define i8 @test_icmp_trunc4(i64 %n) {
430 ; CHECK-LABEL: @test_icmp_trunc4(
431 ; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[N:%.*]] to i32
432 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[CONV]], 10
433 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
435 ; CHECK-NEXT: [[CONV2:%.*]] = trunc i64 [[N]] to i8
436 ; CHECK-NEXT: [[ADD:%.*]] = or disjoint i8 [[CONV2]], 48
437 ; CHECK-NEXT: ret i8 [[ADD]]
439 ; CHECK-NEXT: ret i8 0
441 %conv = trunc i64 %n to i32
442 %cmp = icmp ult i32 %conv, 10
443 br i1 %cmp, label %if.then, label %if.else
446 %conv2 = trunc i64 %n to i8
447 %add = add i8 %conv2, 48
454 define i64 @test_icmp_trunc5(i64 %n) {
455 ; CHECK-LABEL: @test_icmp_trunc5(
457 ; CHECK-NEXT: [[SHR:%.*]] = ashr i64 [[N:%.*]], 47
458 ; CHECK-NEXT: [[CONV1:%.*]] = trunc nsw i64 [[SHR]] to i32
459 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[CONV1]], -13
460 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
462 ; CHECK-NEXT: [[TMP0:%.*]] = and i64 [[SHR]], 15
463 ; CHECK-NEXT: [[NOT:%.*]] = xor i64 [[TMP0]], 15
464 ; CHECK-NEXT: ret i64 [[NOT]]
466 ; CHECK-NEXT: ret i64 13
469 %shr = ashr i64 %n, 47
470 %conv1 = trunc i64 %shr to i32
471 %cmp = icmp ugt i32 %conv1, -13
472 br i1 %cmp, label %if.then, label %if.else
475 %and = and i64 %shr, 4294967295
476 %not = xor i64 %and, 4294967295
483 define i1 @test_icmp_or_distjoint(i8 %n, i1 %other) {
484 ; CHECK-LABEL: @test_icmp_or_distjoint(
486 ; CHECK-NEXT: [[N_OR:%.*]] = or disjoint i8 [[N:%.*]], 16
487 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_OR]], -111
488 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
490 ; CHECK-NEXT: ret i1 true
492 ; CHECK-NEXT: ret i1 [[OTHER:%.*]]
495 %n_or = or disjoint i8 %n, 16
496 %cmp = icmp ugt i8 %n_or, 145
497 br i1 %cmp, label %if.then, label %if.else
500 %r = icmp slt i8 %n, 0
507 define i1 @test_icmp_or_fail_missing_disjoint(i8 %n, i1 %other) {
508 ; CHECK-LABEL: @test_icmp_or_fail_missing_disjoint(
510 ; CHECK-NEXT: [[N_OR:%.*]] = or i8 [[N:%.*]], 16
511 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_OR]], -111
512 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
514 ; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[N]], 0
515 ; CHECK-NEXT: ret i1 [[R]]
517 ; CHECK-NEXT: ret i1 [[OTHER:%.*]]
521 %cmp = icmp ugt i8 %n_or, 145
522 br i1 %cmp, label %if.then, label %if.else
525 %r = icmp slt i8 %n, 0
532 define i8 @and_eq_bits_must_be_set(i8 %x, i8 %y) {
533 ; CHECK-LABEL: @and_eq_bits_must_be_set(
534 ; CHECK-NEXT: [[XY:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
535 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[XY]], 123
536 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
537 ; CHECK-NEXT: ret i8 1
540 %cmp = icmp eq i8 %xy, 123
541 call void @llvm.assume(i1 %cmp)
546 define i8 @test_icmp_or(i8 %n, i8 %n2, i8 %other) {
547 ; CHECK-LABEL: @test_icmp_or(
549 ; CHECK-NEXT: [[N_OR:%.*]] = or i8 [[N:%.*]], [[N2:%.*]]
550 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_OR]], 32
551 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
553 ; CHECK-NEXT: ret i8 0
555 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
558 %n_or = or i8 %n, %n2
559 %cmp = icmp ult i8 %n_or, 32
560 br i1 %cmp, label %if.then, label %if.else
570 define i8 @test_icmp_or2(i8 %n, i8 %n2, i8 %other) {
571 ; CHECK-LABEL: @test_icmp_or2(
573 ; CHECK-NEXT: [[N_OR:%.*]] = or i8 [[N:%.*]], [[N2:%.*]]
574 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_OR]], 14
575 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
577 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
579 ; CHECK-NEXT: ret i8 0
582 %n_or = or i8 %n, %n2
583 %cmp = icmp uge i8 %n_or, 15
584 br i1 %cmp, label %if.then, label %if.else
594 define i8 @test_icmp_or_fail_bad_range(i8 %n, i8 %n2, i8 %other) {
595 ; CHECK-LABEL: @test_icmp_or_fail_bad_range(
597 ; CHECK-NEXT: [[N_OR:%.*]] = or i8 [[N:%.*]], [[N2:%.*]]
598 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_OR]], 33
599 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
601 ; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
602 ; CHECK-NEXT: ret i8 [[R]]
604 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
607 %n_or = or i8 %n, %n2
608 %cmp = icmp ule i8 %n_or, 32
609 br i1 %cmp, label %if.then, label %if.else
619 define i8 @test_icmp_or_fail_bad_pred(i8 %n, i8 %n2, i8 %other) {
620 ; CHECK-LABEL: @test_icmp_or_fail_bad_pred(
622 ; CHECK-NEXT: [[N_OR:%.*]] = or i8 [[N:%.*]], [[N2:%.*]]
623 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_OR]], 32
624 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
626 ; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
627 ; CHECK-NEXT: ret i8 [[R]]
629 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
632 %n_or = or i8 %n, %n2
633 %cmp = icmp ugt i8 %n_or, 32
634 br i1 %cmp, label %if.then, label %if.else
644 define i8 @test_icmp_and(i8 %n, i8 %n2, i8 %other) {
645 ; CHECK-LABEL: @test_icmp_and(
647 ; CHECK-NEXT: [[N_AND:%.*]] = and i8 [[N:%.*]], [[N2:%.*]]
648 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_AND]], -33
649 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
651 ; CHECK-NEXT: ret i8 32
653 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
656 %n_and = and i8 %n, %n2
657 %cmp = icmp ugt i8 %n_and, 223
658 br i1 %cmp, label %if.then, label %if.else
668 define i8 @test_icmp_and2(i8 %n, i8 %n2, i8 %other) {
669 ; CHECK-LABEL: @test_icmp_and2(
671 ; CHECK-NEXT: [[N_AND:%.*]] = and i8 [[N:%.*]], [[N2:%.*]]
672 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_AND]], -31
673 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
675 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
677 ; CHECK-NEXT: ret i8 32
680 %n_and = and i8 %n, %n2
681 %cmp = icmp ule i8 %n_and, 224
682 br i1 %cmp, label %if.then, label %if.else
692 define i8 @test_icmp_and_fail_bad_range(i8 %n, i8 %n2, i8 %other) {
693 ; CHECK-LABEL: @test_icmp_and_fail_bad_range(
695 ; CHECK-NEXT: [[N_AND:%.*]] = and i8 [[N:%.*]], [[N2:%.*]]
696 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_AND]], -34
697 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
699 ; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
700 ; CHECK-NEXT: ret i8 [[R]]
702 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
705 %n_and = and i8 %n, %n2
706 %cmp = icmp uge i8 %n_and, 223
707 br i1 %cmp, label %if.then, label %if.else
717 define i8 @test_icmp_and_fail_bad_pred(i8 %n, i8 %n2, i8 %other) {
718 ; CHECK-LABEL: @test_icmp_and_fail_bad_pred(
720 ; CHECK-NEXT: [[N_AND:%.*]] = and i8 [[N:%.*]], [[N2:%.*]]
721 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[N_AND]], 31
722 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
724 ; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
725 ; CHECK-NEXT: ret i8 [[R]]
727 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
730 %n_and = and i8 %n, %n2
731 %cmp = icmp sge i8 %n_and, 32
732 br i1 %cmp, label %if.then, label %if.else
742 define i8 @and_eq_bits_must_be_set2(i8 %x, i8 %y) {
743 ; CHECK-LABEL: @and_eq_bits_must_be_set2(
744 ; CHECK-NEXT: [[XY:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
745 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[XY]], 123
746 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
747 ; CHECK-NEXT: ret i8 11
750 %cmp = icmp eq i8 %xy, 123
751 call void @llvm.assume(i1 %cmp)
756 define i8 @and_eq_bits_must_be_set2_partial_fail(i8 %x, i8 %y) {
757 ; CHECK-LABEL: @and_eq_bits_must_be_set2_partial_fail(
758 ; CHECK-NEXT: [[XY:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
759 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[XY]], 123
760 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
761 ; CHECK-NEXT: [[R:%.*]] = and i8 [[Y]], 111
762 ; CHECK-NEXT: ret i8 [[R]]
765 %cmp = icmp eq i8 %xy, 123
766 call void @llvm.assume(i1 %cmp)
771 define i8 @or_eq_bits_must_be_unset(i8 %x, i8 %y) {
772 ; CHECK-LABEL: @or_eq_bits_must_be_unset(
773 ; CHECK-NEXT: [[XY:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
774 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[XY]], 124
775 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
776 ; CHECK-NEXT: ret i8 0
779 %cmp = icmp eq i8 %xy, 124
780 call void @llvm.assume(i1 %cmp)
785 define i8 @or_eq_bits_must_be_unset2(i8 %x, i8 %y) {
786 ; CHECK-LABEL: @or_eq_bits_must_be_unset2(
787 ; CHECK-NEXT: [[XY:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
788 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[XY]], 124
789 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
790 ; CHECK-NEXT: ret i8 0
793 %cmp = icmp eq i8 %xy, 124
794 call void @llvm.assume(i1 %cmp)
799 define i8 @or_eq_bits_must_be_unset2_partial_fail(i8 %x, i8 %y) {
800 ; CHECK-LABEL: @or_eq_bits_must_be_unset2_partial_fail(
801 ; CHECK-NEXT: [[XY:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
802 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[XY]], 124
803 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
804 ; CHECK-NEXT: [[R:%.*]] = and i8 [[Y]], 4
805 ; CHECK-NEXT: ret i8 [[R]]
808 %cmp = icmp eq i8 %xy, 124
809 call void @llvm.assume(i1 %cmp)
814 define i8 @or_ne_bits_must_be_unset2_fail(i8 %x, i8 %y) {
815 ; CHECK-LABEL: @or_ne_bits_must_be_unset2_fail(
816 ; CHECK-NEXT: [[XY:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
817 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[XY]], 124
818 ; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
819 ; CHECK-NEXT: [[R:%.*]] = and i8 [[X]], 3
820 ; CHECK-NEXT: ret i8 [[R]]
823 %cmp = icmp ne i8 %xy, 124
824 call void @llvm.assume(i1 %cmp)
829 declare void @use.i1(i1)
830 declare void @use.i8(i8)
832 declare void @use.2xi1(<2 x i1>)
834 define i1 @extract_value_uadd(<2 x i8> %xx, <2 x i8> %yy) {
835 ; CHECK-LABEL: @extract_value_uadd(
836 ; CHECK-NEXT: [[X0:%.*]] = and <2 x i8> [[XX:%.*]], <i8 63, i8 -1>
837 ; CHECK-NEXT: [[Y0:%.*]] = and <2 x i8> [[YY:%.*]], <i8 63, i8 -1>
838 ; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], <i8 1, i8 0>
839 ; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], <i8 1, i8 0>
840 ; CHECK-NEXT: [[ADD_UOV:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow.v2i8(<2 x i8> [[X]], <2 x i8> [[Y]])
841 ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1
842 ; CHECK-NEXT: call void @use.2xi1(<2 x i1> [[UOV]])
843 ; CHECK-NEXT: ret i1 false
845 %x0 = and <2 x i8> %xx, <i8 63, i8 255>
846 %y0 = and <2 x i8> %yy, <i8 63, i8 255>
847 %x = add nuw <2 x i8> %x0, <i8 1, i8 0>
848 %y = add nuw <2 x i8> %y0, <i8 1, i8 0>
850 %add_uov = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow(<2 x i8> %x, <2 x i8> %y)
851 %add = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 0
852 %uov = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 1
853 call void @use.2xi1(<2 x i1> %uov)
854 %add_ele = extractelement <2 x i8> %add, i32 0
855 %r = icmp eq i8 %add_ele, 0
859 define i1 @extract_value_uadd2(<2 x i8> %xx, <2 x i8> %yy) {
860 ; CHECK-LABEL: @extract_value_uadd2(
861 ; CHECK-NEXT: [[X0:%.*]] = and <2 x i8> [[XX:%.*]], <i8 -1, i8 63>
862 ; CHECK-NEXT: [[Y0:%.*]] = and <2 x i8> [[YY:%.*]], <i8 -1, i8 63>
863 ; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], <i8 0, i8 1>
864 ; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], <i8 0, i8 1>
865 ; CHECK-NEXT: [[ADD_UOV:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow.v2i8(<2 x i8> [[X]], <2 x i8> [[Y]])
866 ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1
867 ; CHECK-NEXT: call void @use.2xi1(<2 x i1> [[UOV]])
868 ; CHECK-NEXT: ret i1 false
870 %x0 = and <2 x i8> %xx, <i8 255, i8 63>
871 %y0 = and <2 x i8> %yy, <i8 255, i8 63>
872 %x = add nuw <2 x i8> %x0, <i8 0, i8 1>
873 %y = add nuw <2 x i8> %y0, <i8 0, i8 1>
875 %add_uov = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow(<2 x i8> %x, <2 x i8> %y)
876 %add = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 0
877 %uov = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 1
878 call void @use.2xi1(<2 x i1> %uov)
879 %add_ele = extractelement <2 x i8> %add, i32 1
880 %r = icmp eq i8 %add_ele, 0
884 define i1 @extract_value_uadd_fail(<2 x i8> %xx, <2 x i8> %yy) {
885 ; CHECK-LABEL: @extract_value_uadd_fail(
886 ; CHECK-NEXT: [[X0:%.*]] = and <2 x i8> [[XX:%.*]], <i8 63, i8 -1>
887 ; CHECK-NEXT: [[Y0:%.*]] = and <2 x i8> [[YY:%.*]], <i8 63, i8 -1>
888 ; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], <i8 1, i8 0>
889 ; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], <i8 1, i8 0>
890 ; CHECK-NEXT: [[ADD_UOV:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow.v2i8(<2 x i8> [[X]], <2 x i8> [[Y]])
891 ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 0
892 ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1
893 ; CHECK-NEXT: call void @use.2xi1(<2 x i1> [[UOV]])
894 ; CHECK-NEXT: [[ADD_ELE:%.*]] = extractelement <2 x i8> [[ADD]], i64 1
895 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD_ELE]], 0
896 ; CHECK-NEXT: ret i1 [[R]]
898 %x0 = and <2 x i8> %xx, <i8 63, i8 255>
899 %y0 = and <2 x i8> %yy, <i8 63, i8 255>
900 %x = add nuw <2 x i8> %x0, <i8 1, i8 0>
901 %y = add nuw <2 x i8> %y0, <i8 1, i8 0>
903 %add_uov = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow(<2 x i8> %x, <2 x i8> %y)
904 %add = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 0
905 %uov = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 1
906 call void @use.2xi1(<2 x i1> %uov)
907 %add_ele = extractelement <2 x i8> %add, i32 1
908 %r = icmp eq i8 %add_ele, 0
912 define i1 @extract_value_uadd_fail2(<2 x i8> %xx, <2 x i8> %yy, i32 %idx) {
913 ; CHECK-LABEL: @extract_value_uadd_fail2(
914 ; CHECK-NEXT: [[X0:%.*]] = and <2 x i8> [[XX:%.*]], <i8 63, i8 -1>
915 ; CHECK-NEXT: [[Y0:%.*]] = and <2 x i8> [[YY:%.*]], <i8 63, i8 -1>
916 ; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], <i8 1, i8 0>
917 ; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], <i8 1, i8 0>
918 ; CHECK-NEXT: [[ADD_UOV:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow.v2i8(<2 x i8> [[X]], <2 x i8> [[Y]])
919 ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 0
920 ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1
921 ; CHECK-NEXT: call void @use.2xi1(<2 x i1> [[UOV]])
922 ; CHECK-NEXT: [[ADD_ELE:%.*]] = extractelement <2 x i8> [[ADD]], i32 [[IDX:%.*]]
923 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD_ELE]], 0
924 ; CHECK-NEXT: ret i1 [[R]]
926 %x0 = and <2 x i8> %xx, <i8 63, i8 255>
927 %y0 = and <2 x i8> %yy, <i8 63, i8 255>
928 %x = add nuw <2 x i8> %x0, <i8 1, i8 0>
929 %y = add nuw <2 x i8> %y0, <i8 1, i8 0>
931 %add_uov = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow(<2 x i8> %x, <2 x i8> %y)
932 %add = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 0
933 %uov = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 1
934 call void @use.2xi1(<2 x i1> %uov)
935 %add_ele = extractelement <2 x i8> %add, i32 %idx
936 %r = icmp eq i8 %add_ele, 0
940 define i1 @extract_value_uadd_fail3(<2 x i8> %xx, <2 x i8> %yy) {
941 ; CHECK-LABEL: @extract_value_uadd_fail3(
942 ; CHECK-NEXT: [[X0:%.*]] = and <2 x i8> [[XX:%.*]], splat (i8 127)
943 ; CHECK-NEXT: [[Y0:%.*]] = and <2 x i8> [[YY:%.*]], splat (i8 127)
944 ; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[X0]], splat (i8 1)
945 ; CHECK-NEXT: [[Y:%.*]] = add nuw <2 x i8> [[Y0]], splat (i8 1)
946 ; CHECK-NEXT: [[ADD_UOV:%.*]] = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow.v2i8(<2 x i8> [[X]], <2 x i8> [[Y]])
947 ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 0
948 ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { <2 x i8>, <2 x i1> } [[ADD_UOV]], 1
949 ; CHECK-NEXT: call void @use.2xi1(<2 x i1> [[UOV]])
950 ; CHECK-NEXT: [[ADD_ELE:%.*]] = extractelement <2 x i8> [[ADD]], i64 0
951 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD_ELE]], 0
952 ; CHECK-NEXT: ret i1 [[R]]
954 %x0 = and <2 x i8> %xx, <i8 127, i8 127>
955 %y0 = and <2 x i8> %yy, <i8 127, i8 127>
956 %x = add nuw <2 x i8> %x0, <i8 1, i8 1>
957 %y = add nuw <2 x i8> %y0, <i8 1, i8 1>
959 %add_uov = call { <2 x i8>, <2 x i1> } @llvm.uadd.with.overflow(<2 x i8> %x, <2 x i8> %y)
960 %add = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 0
961 %uov = extractvalue { <2 x i8>, <2 x i1> } %add_uov, 1
962 call void @use.2xi1(<2 x i1> %uov)
963 %add_ele = extractelement <2 x i8> %add, i32 0
964 %r = icmp eq i8 %add_ele, 0
968 define i1 @extract_value_sadd(i8 %xx, i8 %yy) {
969 ; CHECK-LABEL: @extract_value_sadd(
970 ; CHECK-NEXT: [[X:%.*]] = add nuw i8 [[XX:%.*]], 1
971 ; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
972 ; CHECK-NEXT: [[X_LEMMA:%.*]] = icmp sgt i8 [[X]], -1
973 ; CHECK-NEXT: [[Y_LEMMA:%.*]] = icmp sgt i8 [[Y]], -1
974 ; CHECK-NEXT: call void @llvm.assume(i1 [[X_LEMMA]])
975 ; CHECK-NEXT: call void @llvm.assume(i1 [[Y_LEMMA]])
976 ; CHECK-NEXT: [[ADD_SOV:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X]], i8 [[Y]])
977 ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 1
978 ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
979 ; CHECK-NEXT: ret i1 false
981 %x = add nuw i8 %xx, 1
982 %y = add nuw i8 %yy, 1
983 %x_lemma = icmp ult i8 %x, 128
984 %y_lemma = icmp ult i8 %y, 128
985 call void @llvm.assume(i1 %x_lemma)
986 call void @llvm.assume(i1 %y_lemma)
988 %add_sov = call { i8, i1 } @llvm.sadd.with.overflow(i8 %x, i8 %y)
989 %add = extractvalue { i8, i1 } %add_sov, 0
990 %sov = extractvalue { i8, i1 } %add_sov, 1
991 call void @use.i1(i1 %sov)
992 %r = icmp eq i8 %add, 0
996 define i1 @extract_value_sadd_fail(i8 %xx, i8 %yy) {
997 ; CHECK-LABEL: @extract_value_sadd_fail(
998 ; CHECK-NEXT: [[X:%.*]] = add i8 [[XX:%.*]], 1
999 ; CHECK-NEXT: [[Y:%.*]] = add i8 [[YY:%.*]], 1
1000 ; CHECK-NEXT: [[ADD_SOV:%.*]] = call { i8, i1 } @llvm.sadd.with.overflow.i8(i8 [[X]], i8 [[Y]])
1001 ; CHECK-NEXT: [[ADD:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 0
1002 ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[ADD_SOV]], 1
1003 ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
1004 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[ADD]], 0
1005 ; CHECK-NEXT: ret i1 [[R]]
1010 %add_sov = call { i8, i1 } @llvm.sadd.with.overflow(i8 %x, i8 %y)
1011 %add = extractvalue { i8, i1 } %add_sov, 0
1012 %sov = extractvalue { i8, i1 } %add_sov, 1
1013 call void @use.i1(i1 %sov)
1014 %r = icmp eq i8 %add, 0
1018 define i1 @extract_value_usub(i8 %x, i8 %zz) {
1019 ; CHECK-LABEL: @extract_value_usub(
1020 ; CHECK-NEXT: [[Z:%.*]] = add nuw i8 [[ZZ:%.*]], 1
1021 ; CHECK-NEXT: [[Y:%.*]] = add i8 [[X:%.*]], [[Z]]
1022 ; CHECK-NEXT: [[SUB_UOV:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X]], i8 [[Y]])
1023 ; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 0
1024 ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 1
1025 ; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
1026 ; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
1027 ; CHECK-NEXT: ret i1 false
1029 %z = add nuw i8 %zz, 1
1032 %sub_uov = call { i8, i1 } @llvm.usub.with.overflow(i8 %x, i8 %y)
1033 %sub = extractvalue { i8, i1 } %sub_uov, 0
1034 %uov = extractvalue { i8, i1 } %sub_uov, 1
1035 call void @use.i1(i1 %uov)
1036 call void @use.i8(i8 %sub)
1037 %r = icmp eq i8 %sub, 0
1041 define i1 @extract_value_usub_fail(i8 %x, i8 %z) {
1042 ; CHECK-LABEL: @extract_value_usub_fail(
1043 ; CHECK-NEXT: [[Y:%.*]] = add i8 [[X:%.*]], [[Z:%.*]]
1044 ; CHECK-NEXT: [[SUB_UOV:%.*]] = call { i8, i1 } @llvm.usub.with.overflow.i8(i8 [[X]], i8 [[Y]])
1045 ; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 0
1046 ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[SUB_UOV]], 1
1047 ; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
1048 ; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
1049 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0
1050 ; CHECK-NEXT: ret i1 [[R]]
1053 %sub_uov = call { i8, i1 } @llvm.usub.with.overflow(i8 %x, i8 %y)
1054 %sub = extractvalue { i8, i1 } %sub_uov, 0
1055 %uov = extractvalue { i8, i1 } %sub_uov, 1
1056 call void @use.i1(i1 %uov)
1057 call void @use.i8(i8 %sub)
1058 %r = icmp eq i8 %sub, 0
1062 define i1 @extract_value_ssub(i8 %x, i8 %zz) {
1063 ; CHECK-LABEL: @extract_value_ssub(
1064 ; CHECK-NEXT: [[Z:%.*]] = add nuw i8 [[ZZ:%.*]], 1
1065 ; CHECK-NEXT: [[Y:%.*]] = add i8 [[X:%.*]], [[Z]]
1066 ; CHECK-NEXT: [[SUB_SOV:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 [[Y]], i8 [[X]])
1067 ; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 0
1068 ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 1
1069 ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
1070 ; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
1071 ; CHECK-NEXT: ret i1 false
1073 %z = add nuw i8 %zz, 1
1076 %sub_sov = call { i8, i1 } @llvm.ssub.with.overflow(i8 %y, i8 %x)
1077 %sub = extractvalue { i8, i1 } %sub_sov, 0
1078 %sov = extractvalue { i8, i1 } %sub_sov, 1
1079 call void @use.i1(i1 %sov)
1080 call void @use.i8(i8 %sub)
1081 %r = icmp eq i8 %sub, 0
1085 define i1 @extract_value_ssub_fail(i8 %x) {
1086 ; CHECK-LABEL: @extract_value_ssub_fail(
1087 ; CHECK-NEXT: [[SUB_SOV:%.*]] = call { i8, i1 } @llvm.ssub.with.overflow.i8(i8 10, i8 [[X:%.*]])
1088 ; CHECK-NEXT: [[SUB:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 0
1089 ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[SUB_SOV]], 1
1090 ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
1091 ; CHECK-NEXT: call void @use.i8(i8 [[SUB]])
1092 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[SUB]], 0
1093 ; CHECK-NEXT: ret i1 [[R]]
1095 %sub_sov = call { i8, i1 } @llvm.ssub.with.overflow(i8 10, i8 %x)
1096 %sub = extractvalue { i8, i1 } %sub_sov, 0
1097 %sov = extractvalue { i8, i1 } %sub_sov, 1
1098 call void @use.i1(i1 %sov)
1099 call void @use.i8(i8 %sub)
1100 %r = icmp eq i8 %sub, 0
1104 define i1 @extract_value_umul(i8 %xx, i8 %yy) {
1105 ; CHECK-LABEL: @extract_value_umul(
1106 ; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 1
1107 ; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
1108 ; CHECK-NEXT: [[MUL_UOV:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[X]], i8 [[Y]])
1109 ; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 0
1110 ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 1
1111 ; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
1112 ; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
1113 ; CHECK-NEXT: ret i1 false
1116 %y = add nuw i8 %yy, 1
1118 %mul_uov = call { i8, i1 } @llvm.umul.with.overflow(i8 %x, i8 %y)
1119 %mul = extractvalue { i8, i1 } %mul_uov, 0
1120 %uov = extractvalue { i8, i1 } %mul_uov, 1
1121 call void @use.i1(i1 %uov)
1122 call void @use.i8(i8 %mul)
1123 %r = icmp eq i8 %mul, 0
1127 define i1 @extract_value_umul_fail(i8 %xx, i8 %yy) {
1128 ; CHECK-LABEL: @extract_value_umul_fail(
1129 ; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 2
1130 ; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
1131 ; CHECK-NEXT: [[MUL_UOV:%.*]] = call { i8, i1 } @llvm.umul.with.overflow.i8(i8 [[X]], i8 [[Y]])
1132 ; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 0
1133 ; CHECK-NEXT: [[UOV:%.*]] = extractvalue { i8, i1 } [[MUL_UOV]], 1
1134 ; CHECK-NEXT: call void @use.i1(i1 [[UOV]])
1135 ; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
1136 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0
1137 ; CHECK-NEXT: ret i1 [[R]]
1140 %y = add nuw i8 %yy, 1
1142 %mul_uov = call { i8, i1 } @llvm.umul.with.overflow(i8 %x, i8 %y)
1143 %mul = extractvalue { i8, i1 } %mul_uov, 0
1144 %uov = extractvalue { i8, i1 } %mul_uov, 1
1145 call void @use.i1(i1 %uov)
1146 call void @use.i8(i8 %mul)
1147 %r = icmp eq i8 %mul, 0
1151 define i1 @extract_value_smul(i8 %xx, i8 %yy) {
1152 ; CHECK-LABEL: @extract_value_smul(
1153 ; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 1
1154 ; CHECK-NEXT: [[Y:%.*]] = add nuw i8 [[YY:%.*]], 1
1155 ; CHECK-NEXT: [[MUL_SOV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[Y]], i8 [[X]])
1156 ; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 0
1157 ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 1
1158 ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
1159 ; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
1160 ; CHECK-NEXT: ret i1 false
1163 %y = add nuw i8 %yy, 1
1165 %mul_sov = call { i8, i1 } @llvm.smul.with.overflow(i8 %y, i8 %x)
1166 %mul = extractvalue { i8, i1 } %mul_sov, 0
1167 %sov = extractvalue { i8, i1 } %mul_sov, 1
1168 call void @use.i1(i1 %sov)
1169 call void @use.i8(i8 %mul)
1170 %r = icmp eq i8 %mul, 0
1174 define i1 @extract_value_smul_fail(i8 %xx, i8 %yy) {
1175 ; CHECK-LABEL: @extract_value_smul_fail(
1176 ; CHECK-NEXT: [[X:%.*]] = or i8 [[XX:%.*]], 1
1177 ; CHECK-NEXT: [[Y:%.*]] = add i8 [[YY:%.*]], 1
1178 ; CHECK-NEXT: [[MUL_SOV:%.*]] = call { i8, i1 } @llvm.smul.with.overflow.i8(i8 [[Y]], i8 [[X]])
1179 ; CHECK-NEXT: [[MUL:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 0
1180 ; CHECK-NEXT: [[SOV:%.*]] = extractvalue { i8, i1 } [[MUL_SOV]], 1
1181 ; CHECK-NEXT: call void @use.i1(i1 [[SOV]])
1182 ; CHECK-NEXT: call void @use.i8(i8 [[MUL]])
1183 ; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[MUL]], 0
1184 ; CHECK-NEXT: ret i1 [[R]]
1189 %mul_sov = call { i8, i1 } @llvm.smul.with.overflow(i8 %y, i8 %x)
1190 %mul = extractvalue { i8, i1 } %mul_sov, 0
1191 %sov = extractvalue { i8, i1 } %mul_sov, 1
1192 call void @use.i1(i1 %sov)
1193 call void @use.i8(i8 %mul)
1194 %r = icmp eq i8 %mul, 0
1198 define i8 @known_reduce_or(<2 x i8> %xx) {
1199 ; CHECK-LABEL: @known_reduce_or(
1200 ; CHECK-NEXT: ret i8 1
1202 %x = or <2 x i8> %xx, <i8 5, i8 3>
1203 %v = call i8 @llvm.vector.reduce.or(<2 x i8> %x)
1208 define i8 @known_reduce_or_fail(<2 x i8> %xx) {
1209 ; CHECK-LABEL: @known_reduce_or_fail(
1210 ; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3>
1211 ; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.or.v2i8(<2 x i8> [[X]])
1212 ; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 4
1213 ; CHECK-NEXT: ret i8 [[R]]
1215 %x = or <2 x i8> %xx, <i8 5, i8 3>
1216 %v = call i8 @llvm.vector.reduce.or(<2 x i8> %x)
1221 define i8 @known_reduce_and(<2 x i8> %xx) {
1222 ; CHECK-LABEL: @known_reduce_and(
1223 ; CHECK-NEXT: ret i8 1
1225 %x = or <2 x i8> %xx, <i8 5, i8 3>
1226 %v = call i8 @llvm.vector.reduce.and(<2 x i8> %x)
1231 define i8 @known_reduce_and_fail(<2 x i8> %xx) {
1232 ; CHECK-LABEL: @known_reduce_and_fail(
1233 ; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3>
1234 ; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.and.v2i8(<2 x i8> [[X]])
1235 ; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 2
1236 ; CHECK-NEXT: ret i8 [[R]]
1238 %x = or <2 x i8> %xx, <i8 5, i8 3>
1239 %v = call i8 @llvm.vector.reduce.and(<2 x i8> %x)
1244 define i8 @known_reduce_xor_even(<2 x i8> %xx) {
1245 ; CHECK-LABEL: @known_reduce_xor_even(
1246 ; CHECK-NEXT: ret i8 0
1248 %x = or <2 x i8> %xx, <i8 5, i8 3>
1249 %v = call i8 @llvm.vector.reduce.xor(<2 x i8> %x)
1254 define i8 @known_reduce_xor_even2(<2 x i8> %xx) {
1255 ; CHECK-LABEL: @known_reduce_xor_even2(
1256 ; CHECK-NEXT: ret i8 0
1258 %x = and <2 x i8> %xx, <i8 15, i8 15>
1259 %v = call i8 @llvm.vector.reduce.xor(<2 x i8> %x)
1264 define i8 @known_reduce_xor_even_fail(<2 x i8> %xx) {
1265 ; CHECK-LABEL: @known_reduce_xor_even_fail(
1266 ; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3>
1267 ; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v2i8(<2 x i8> [[X]])
1268 ; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 2
1269 ; CHECK-NEXT: ret i8 [[R]]
1271 %x = or <2 x i8> %xx, <i8 5, i8 3>
1272 %v = call i8 @llvm.vector.reduce.xor(<2 x i8> %x)
1277 define i8 @known_reduce_xor_odd(<3 x i8> %xx) {
1278 ; CHECK-LABEL: @known_reduce_xor_odd(
1279 ; CHECK-NEXT: ret i8 1
1281 %x = or <3 x i8> %xx, <i8 5, i8 3, i8 9>
1282 %v = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> %x)
1287 define i8 @known_reduce_xor_odd2(<3 x i8> %xx) {
1288 ; CHECK-LABEL: @known_reduce_xor_odd2(
1289 ; CHECK-NEXT: ret i8 0
1291 %x = and <3 x i8> %xx, <i8 15, i8 15, i8 31>
1292 %v = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> %x)
1297 define i8 @known_reduce_xor_odd2_fail(<3 x i8> %xx) {
1298 ; CHECK-LABEL: @known_reduce_xor_odd2_fail(
1299 ; CHECK-NEXT: [[X:%.*]] = and <3 x i8> [[XX:%.*]], <i8 15, i8 15, i8 31>
1300 ; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> [[X]])
1301 ; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 16
1302 ; CHECK-NEXT: ret i8 [[R]]
1304 %x = and <3 x i8> %xx, <i8 15, i8 15, i8 31>
1305 %v = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> %x)
1310 define i8 @known_reduce_xor_odd_fail(<3 x i8> %xx) {
1311 ; CHECK-LABEL: @known_reduce_xor_odd_fail(
1312 ; CHECK-NEXT: [[X:%.*]] = or <3 x i8> [[XX:%.*]], <i8 5, i8 3, i8 9>
1313 ; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> [[X]])
1314 ; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 2
1315 ; CHECK-NEXT: ret i8 [[R]]
1317 %x = or <3 x i8> %xx, <i8 5, i8 3, i8 9>
1318 %v = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> %x)
1323 define i8 @nonzero_reduce_xor_vscale_even(<vscale x 2 x i8> %xx) {
1324 ; CHECK-LABEL: @nonzero_reduce_xor_vscale_even(
1325 ; CHECK-NEXT: ret i8 0
1327 %one = insertelement <vscale x 2 x i8> poison, i8 1, i64 0
1328 %ones = shufflevector <vscale x 2 x i8> %one, <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer
1329 %x = or <vscale x 2 x i8> %xx, %ones
1330 %v = call i8 @llvm.vector.reduce.xor.nxv2i8(<vscale x 2 x i8> %x)
1335 define i8 @nonzero_reduce_xor_vscale_odd_fail(<vscale x 3 x i8> %xx) {
1336 ; CHECK-LABEL: @nonzero_reduce_xor_vscale_odd_fail(
1337 ; CHECK-NEXT: [[X:%.*]] = or <vscale x 3 x i8> [[XX:%.*]], splat (i8 1)
1338 ; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.nxv3i8(<vscale x 3 x i8> [[X]])
1339 ; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
1340 ; CHECK-NEXT: ret i8 [[R]]
1342 %one = insertelement <vscale x 3 x i8> poison, i8 1, i64 0
1343 %ones = shufflevector <vscale x 3 x i8> %one, <vscale x 3 x i8> poison, <vscale x 3 x i32> zeroinitializer
1344 %x = or <vscale x 3 x i8> %xx, %ones
1345 %v = call i8 @llvm.vector.reduce.xor.nxv3i8(<vscale x 3 x i8> %x)
1350 define i8 @nonzero_reduce_xor_vscale_even_fail(<vscale x 2 x i8> %xx) {
1351 ; CHECK-LABEL: @nonzero_reduce_xor_vscale_even_fail(
1352 ; CHECK-NEXT: [[X:%.*]] = or <vscale x 2 x i8> [[XX:%.*]], splat (i8 1)
1353 ; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.nxv2i8(<vscale x 2 x i8> [[X]])
1354 ; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 2
1355 ; CHECK-NEXT: ret i8 [[R]]
1357 %one = insertelement <vscale x 2 x i8> poison, i8 1, i64 0
1358 %ones = shufflevector <vscale x 2 x i8> %one, <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer
1359 %x = or <vscale x 2 x i8> %xx, %ones
1360 %v = call i8 @llvm.vector.reduce.xor.nxv2i8(<vscale x 2 x i8> %x)
1365 define i8 @nonzero_reduce_xor_vscale_odd(<vscale x 3 x i8> %xx) {
1366 ; CHECK-LABEL: @nonzero_reduce_xor_vscale_odd(
1367 ; CHECK-NEXT: ret i8 0
1369 %one = insertelement <vscale x 3 x i8> poison, i8 1, i64 0
1370 %ones = shufflevector <vscale x 3 x i8> %one, <vscale x 3 x i8> poison, <vscale x 3 x i32> zeroinitializer
1371 %x = and <vscale x 3 x i8> %xx, %ones
1372 %v = call i8 @llvm.vector.reduce.xor.nxv3i8(<vscale x 3 x i8> %x)
1377 define i1 @test_sign_pos(float %x) {
1378 ; CHECK-LABEL: @test_sign_pos(
1379 ; CHECK-NEXT: ret i1 true
1381 %fabs = call float @llvm.fabs.f32(float %x)
1382 %y = bitcast float %fabs to i32
1383 %sign = icmp sgt i32 %y, -1
1387 define i1 @test_sign_pos_half(half %x) {
1388 ; CHECK-LABEL: @test_sign_pos_half(
1389 ; CHECK-NEXT: ret i1 true
1391 %fabs = call half @llvm.fabs.f16(half %x)
1392 %y = bitcast half %fabs to i16
1393 %sign = icmp sgt i16 %y, -1
1397 define i1 @test_sign_pos_half_non_elementwise(<2 x half> %x) {
1398 ; CHECK-LABEL: @test_sign_pos_half_non_elementwise(
1399 ; CHECK-NEXT: [[FABS:%.*]] = call <2 x half> @llvm.fabs.v2f16(<2 x half> [[X:%.*]])
1400 ; CHECK-NEXT: [[Y:%.*]] = bitcast <2 x half> [[FABS]] to i32
1401 ; CHECK-NEXT: [[SIGN:%.*]] = icmp sgt i32 [[Y]], -1
1402 ; CHECK-NEXT: ret i1 [[SIGN]]
1404 %fabs = call <2 x half> @llvm.fabs.v2f16(<2 x half> %x)
1405 %y = bitcast <2 x half> %fabs to i32
1406 %sign = icmp sgt i32 %y, -1
1410 define i1 @test_sign_neg(float %x) {
1411 ; CHECK-LABEL: @test_sign_neg(
1412 ; CHECK-NEXT: ret i1 true
1414 %fabs = call float @llvm.fabs.f32(float %x)
1415 %fnabs = fneg float %fabs
1416 %y = bitcast float %fnabs to i32
1417 %sign = icmp slt i32 %y, 0
1421 define <2 x i1> @test_sign_pos_vec(<2 x float> %x) {
1422 ; CHECK-LABEL: @test_sign_pos_vec(
1423 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
1425 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %x)
1426 %y = bitcast <2 x float> %fabs to <2 x i32>
1427 %sign = icmp slt <2 x i32> %y, zeroinitializer
1431 define i32 @test_inf_only(float nofpclass(nan sub norm zero) %x) {
1432 ; CHECK-LABEL: @test_inf_only(
1433 ; CHECK-NEXT: ret i32 2139095040
1435 %y = bitcast float %x to i32
1436 %and = and i32 %y, 2147483647
1440 define i16 @test_inf_only_bfloat(bfloat nofpclass(nan sub norm zero) %x) {
1441 ; CHECK-LABEL: @test_inf_only_bfloat(
1442 ; CHECK-NEXT: ret i16 32640
1444 %y = bitcast bfloat %x to i16
1445 %and = and i16 %y, 32767
1449 define i128 @test_inf_only_ppc_fp128(ppc_fp128 nofpclass(nan sub norm zero) %x) {
1450 ; CHECK-LABEL: @test_inf_only_ppc_fp128(
1451 ; CHECK-NEXT: ret i128 9218868437227405312
1453 %y = bitcast ppc_fp128 %x to i128
1454 %and = and i128 %y, 170141183460469231731687303715884105727
1458 define i32 @test_zero_only(float nofpclass(nan sub norm inf) %x) {
1459 ; CHECK-LABEL: @test_zero_only(
1460 ; CHECK-NEXT: ret i32 0
1462 %y = bitcast float %x to i32
1463 %and = and i32 %y, 2147483647
1467 define i80 @test_zero_only_non_ieee(x86_fp80 nofpclass(nan sub norm inf) %x) {
1468 ; CHECK-LABEL: @test_zero_only_non_ieee(
1469 ; CHECK-NEXT: ret i80 0
1471 %y = bitcast x86_fp80 %x to i80
1472 %and = and i80 %y, 604462909807314587353087
1476 define i32 @test_inf_nan_only(float nofpclass(sub norm zero) %x) {
1477 ; CHECK-LABEL: @test_inf_nan_only(
1478 ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
1479 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432
1480 ; CHECK-NEXT: ret i32 [[AND]]
1482 %y = bitcast float %x to i32
1483 %and = and i32 %y, 2130706432
1487 define i32 @test_sub_zero_only(float nofpclass(nan norm inf) %x) {
1488 ; CHECK-LABEL: @test_sub_zero_only(
1489 ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
1490 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432
1491 ; CHECK-NEXT: ret i32 [[AND]]
1493 %y = bitcast float %x to i32
1494 %and = and i32 %y, 2130706432
1498 define i32 @test_inf_zero_only(float nofpclass(nan norm sub) %x) {
1499 ; CHECK-LABEL: @test_inf_zero_only(
1500 ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
1501 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 8388608
1502 ; CHECK-NEXT: ret i32 [[AND]]
1504 %y = bitcast float %x to i32
1505 %and = and i32 %y, 16777215
1509 ; Make sure that the signbit is cleared.
1510 define i32 @test_ninf_only(double %x) {
1511 ; CHECK-LABEL: @test_ninf_only(
1512 ; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[X:%.*]], 0xFFF0000000000000
1513 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1515 ; CHECK-NEXT: ret i32 0
1517 ; CHECK-NEXT: ret i32 0
1519 %cmp = fcmp oeq double %x, 0xFFF0000000000000
1520 br i1 %cmp, label %if.then, label %if.else
1523 %cast = bitcast double %x to i64
1524 %trunc = trunc i64 %cast to i32
1531 define i1 @test_simplify_icmp(i32 %x) {
1532 ; CHECK-LABEL: @test_simplify_icmp(
1533 ; CHECK-NEXT: ret i1 false
1535 %cast1 = uitofp i32 %x to double
1536 %cast2 = bitcast double %cast1 to i64
1537 %mask = and i64 %cast2, -140737488355328
1538 %cmp = icmp eq i64 %mask, -1970324836974592
1542 define i32 @test_snan_quiet_bit1(float nofpclass(sub norm inf qnan) %x) {
1543 ; CHECK-LABEL: @test_snan_quiet_bit1(
1544 ; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32
1545 ; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 4194304
1546 ; CHECK-NEXT: ret i32 [[MASKED]]
1548 %bits = bitcast float %x to i32
1549 %masked = and i32 %bits, 4194304
1553 define i32 @test_snan_quiet_bit2(float nofpclass(sub norm inf qnan) %x) {
1554 ; CHECK-LABEL: @test_snan_quiet_bit2(
1555 ; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32
1556 ; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 2097152
1557 ; CHECK-NEXT: ret i32 [[MASKED]]
1559 %bits = bitcast float %x to i32
1560 %masked = and i32 %bits, 2097152
1564 define i32 @test_qnan_quiet_bit1(float nofpclass(sub norm inf snan) %x) {
1565 ; CHECK-LABEL: @test_qnan_quiet_bit1(
1566 ; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32
1567 ; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 4194304
1568 ; CHECK-NEXT: ret i32 [[MASKED]]
1570 %bits = bitcast float %x to i32
1571 %masked = and i32 %bits, 4194304
1575 define i32 @test_qnan_quiet_bit2(float nofpclass(sub norm inf snan) %x) {
1576 ; CHECK-LABEL: @test_qnan_quiet_bit2(
1577 ; CHECK-NEXT: [[BITS:%.*]] = bitcast float [[X:%.*]] to i32
1578 ; CHECK-NEXT: [[MASKED:%.*]] = and i32 [[BITS]], 2097152
1579 ; CHECK-NEXT: ret i32 [[MASKED]]
1581 %bits = bitcast float %x to i32
1582 %masked = and i32 %bits, 2097152
1586 define i16 @test_simplify_mask(i32 %ui, float %x) {
1587 ; CHECK-LABEL: @test_simplify_mask(
1588 ; CHECK-NEXT: [[CONV:%.*]] = uitofp i32 [[UI:%.*]] to float
1589 ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X:%.*]], [[CONV]]
1590 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
1592 ; CHECK-NEXT: ret i16 31744
1594 ; CHECK-NEXT: ret i16 0
1596 %conv = uitofp i32 %ui to float
1597 %cmp = fcmp olt float %x, %conv
1598 br i1 %cmp, label %if.else, label %if.end
1601 %cast = bitcast float %conv to i32
1602 %shr = lshr i32 %cast, 16
1603 %trunc = trunc i32 %shr to i16
1604 %and = and i16 %trunc, -32768
1605 %or = or disjoint i16 %and, 31744
1612 ; TODO: %cmp always evaluates to false
1614 define i1 @test_simplify_icmp2(double %x) {
1615 ; CHECK-LABEL: @test_simplify_icmp2(
1616 ; CHECK-NEXT: [[ABS:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]])
1617 ; CHECK-NEXT: [[COND:%.*]] = fcmp oeq double [[ABS]], 0x7FF0000000000000
1618 ; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1620 ; CHECK-NEXT: [[CAST:%.*]] = bitcast double [[X]] to i64
1621 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[CAST]], 3458764513820540928
1622 ; CHECK-NEXT: ret i1 [[CMP]]
1624 ; CHECK-NEXT: ret i1 false
1626 %abs = tail call double @llvm.fabs.f64(double %x)
1627 %cond = fcmp oeq double %abs, 0x7FF0000000000000
1628 br i1 %cond, label %if.then, label %if.else
1631 %cast = bitcast double %x to i64
1632 %cmp = icmp eq i64 %cast, 3458764513820540928
1639 define i32 @test_snan_only(float nofpclass(qnan sub norm zero inf) %x) {
1640 ; CHECK-LABEL: @test_snan_only(
1641 ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
1642 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 4194304
1643 ; CHECK-NEXT: ret i32 [[AND]]
1645 %y = bitcast float %x to i32
1646 %and = and i32 %y, 4194304
1650 define i32 @test_qnan_only(float nofpclass(snan sub norm zero inf) %x) {
1651 ; CHECK-LABEL: @test_qnan_only(
1652 ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
1653 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 4194304
1654 ; CHECK-NEXT: ret i32 [[AND]]
1656 %y = bitcast float %x to i32
1657 %and = and i32 %y, 4194304
1661 ; Make sure that we don't crash when the use of x is unreachable.
1662 define i64 @pr92084(double %x) {
1663 ; CHECK-LABEL: @pr92084(
1664 ; CHECK-NEXT: [[CMP:%.*]] = fcmp uno double [[X:%.*]], 0.000000e+00
1665 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN1:%.*]], label [[IF_ELSE:%.*]]
1667 ; CHECK-NEXT: br i1 true, label [[IF_ELSE]], label [[IF_THEN2:%.*]]
1669 ; CHECK-NEXT: ret i64 poison
1671 ; CHECK-NEXT: ret i64 0
1673 %cmp = fcmp uno double %x, 0.000000e+00
1674 br i1 %cmp, label %if.then1, label %if.else
1677 br i1 %cmp, label %if.else, label %if.then2
1680 %cast = bitcast double %x to i64
1681 %and = and i64 %cast, 1
1688 define i32 @test_none(float nofpclass(all) %x) {
1689 ; CHECK-LABEL: @test_none(
1690 ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
1691 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 4194304
1692 ; CHECK-NEXT: ret i32 [[AND]]
1694 %y = bitcast float %x to i32
1695 %and = and i32 %y, 4194304
1699 ; We cannot make assumptions about the sign of result of sqrt
1700 ; when the input is a negative value (except for -0).
1701 define i1 @pr92217() {
1702 ; CHECK-LABEL: @pr92217(
1703 ; CHECK-NEXT: [[X:%.*]] = call float @llvm.sqrt.f32(float 0xC6DEBE9E60000000)
1704 ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X]] to i32
1705 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[Y]], 0
1706 ; CHECK-NEXT: ret i1 [[CMP]]
1708 %x = call float @llvm.sqrt.f32(float 0xC6DEBE9E60000000)
1709 %y = bitcast float %x to i32
1710 %cmp = icmp slt i32 %y, 0
1714 define i1 @sqrt_negative_input(float nofpclass(nan zero pnorm psub pinf) %a) {
1715 ; CHECK-LABEL: @sqrt_negative_input(
1716 ; CHECK-NEXT: [[X:%.*]] = call float @llvm.sqrt.f32(float [[A:%.*]])
1717 ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X]] to i32
1718 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[Y]], 0
1719 ; CHECK-NEXT: ret i1 [[CMP]]
1721 %x = call float @llvm.sqrt.f32(float %a)
1722 %y = bitcast float %x to i32
1723 %cmp = icmp slt i32 %y, 0
1727 define i1 @sqrt_negative_input_nnan(float nofpclass(nan zero pnorm psub pinf) %a) {
1728 ; CHECK-LABEL: @sqrt_negative_input_nnan(
1729 ; CHECK-NEXT: ret i1 false
1731 %x = call nnan float @llvm.sqrt.f32(float %a)
1732 %y = bitcast float %x to i32
1733 %cmp = icmp slt i32 %y, 0
1737 define i8 @test_icmp_add(i8 %n, i8 %n2, i8 %other) {
1738 ; CHECK-LABEL: @test_icmp_add(
1739 ; CHECK-NEXT: entry:
1740 ; CHECK-NEXT: [[N_ADD:%.*]] = add nuw i8 [[N:%.*]], [[N2:%.*]]
1741 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_ADD]], 32
1742 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1744 ; CHECK-NEXT: ret i8 0
1746 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
1749 %n_add = add nuw i8 %n, %n2
1750 %cmp = icmp ult i8 %n_add, 32
1751 br i1 %cmp, label %if.then, label %if.else
1761 define i8 @test_icmp_add_fail_nsw(i8 %n, i8 %n2, i8 %other) {
1762 ; CHECK-LABEL: @test_icmp_add_fail_nsw(
1763 ; CHECK-NEXT: entry:
1764 ; CHECK-NEXT: [[N_ADD:%.*]] = add nsw i8 [[N:%.*]], [[N2:%.*]]
1765 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_ADD]], 32
1766 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1768 ; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
1769 ; CHECK-NEXT: ret i8 [[R]]
1771 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
1774 %n_add = add nsw i8 %n, %n2
1775 %cmp = icmp ult i8 %n_add, 32
1776 br i1 %cmp, label %if.then, label %if.else
1786 define i8 @test_icmp_add2(i8 %n, i8 %n2, i8 %other) {
1787 ; CHECK-LABEL: @test_icmp_add2(
1788 ; CHECK-NEXT: entry:
1789 ; CHECK-NEXT: [[N_ADD:%.*]] = add nuw nsw i8 [[N:%.*]], [[N2:%.*]]
1790 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_ADD]], 14
1791 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1793 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
1795 ; CHECK-NEXT: ret i8 0
1798 %n_add = add nsw nuw i8 %n, %n2
1799 %cmp = icmp uge i8 %n_add, 15
1800 br i1 %cmp, label %if.then, label %if.else
1810 define i8 @test_icmp_add_fail_bad_range(i8 %n, i8 %n2, i8 %other) {
1811 ; CHECK-LABEL: @test_icmp_add_fail_bad_range(
1812 ; CHECK-NEXT: entry:
1813 ; CHECK-NEXT: [[N_ADD:%.*]] = add nuw i8 [[N:%.*]], [[N2:%.*]]
1814 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_ADD]], 33
1815 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1817 ; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
1818 ; CHECK-NEXT: ret i8 [[R]]
1820 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
1823 %n_add = add nuw i8 %n, %n2
1824 %cmp = icmp ule i8 %n_add, 32
1825 br i1 %cmp, label %if.then, label %if.else
1835 define i8 @test_icmp_add_fail_bad_pred(i8 %n, i8 %n2, i8 %other) {
1836 ; CHECK-LABEL: @test_icmp_add_fail_bad_pred(
1837 ; CHECK-NEXT: entry:
1838 ; CHECK-NEXT: [[N_ADD:%.*]] = add nuw i8 [[N:%.*]], [[N2:%.*]]
1839 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_ADD]], 32
1840 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1842 ; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
1843 ; CHECK-NEXT: ret i8 [[R]]
1845 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
1848 %n_add = add nuw i8 %n, %n2
1849 %cmp = icmp ugt i8 %n_add, 32
1850 br i1 %cmp, label %if.then, label %if.else
1860 define i8 @test_icmp_sub(i8 %n, i8 %n2, i8 %other) {
1861 ; CHECK-LABEL: @test_icmp_sub(
1862 ; CHECK-NEXT: entry:
1863 ; CHECK-NEXT: [[N_SUB:%.*]] = sub nuw i8 [[N:%.*]], [[N2:%.*]]
1864 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_SUB]], -33
1865 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1867 ; CHECK-NEXT: ret i8 32
1869 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
1872 %n_sub = sub nuw i8 %n, %n2
1873 %cmp = icmp ugt i8 %n_sub, 223
1874 br i1 %cmp, label %if.then, label %if.else
1884 define i8 @test_icmp_sub_fail_wrong_arg(i8 %n, i8 %n2, i8 %other) {
1885 ; CHECK-LABEL: @test_icmp_sub_fail_wrong_arg(
1886 ; CHECK-NEXT: entry:
1887 ; CHECK-NEXT: [[N_SUB:%.*]] = sub nuw i8 [[N:%.*]], [[N2:%.*]]
1888 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_SUB]], -33
1889 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1891 ; CHECK-NEXT: [[R:%.*]] = and i8 [[N2]], 32
1892 ; CHECK-NEXT: ret i8 [[R]]
1894 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
1897 %n_sub = sub nuw i8 %n, %n2
1898 %cmp = icmp ugt i8 %n_sub, 223
1899 br i1 %cmp, label %if.then, label %if.else
1909 define i8 @test_icmp_sub2(i8 %n, i8 %n2, i8 %other) {
1910 ; CHECK-LABEL: @test_icmp_sub2(
1911 ; CHECK-NEXT: entry:
1912 ; CHECK-NEXT: [[N_SUB:%.*]] = sub nuw i8 [[N:%.*]], [[N2:%.*]]
1913 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_SUB]], -31
1914 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1916 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
1918 ; CHECK-NEXT: ret i8 32
1921 %n_sub = sub nuw i8 %n, %n2
1922 %cmp = icmp ule i8 %n_sub, 224
1923 br i1 %cmp, label %if.then, label %if.else
1933 define i8 @test_icmp_sub2_fail_nsw(i8 %n, i8 %n2, i8 %other) {
1934 ; CHECK-LABEL: @test_icmp_sub2_fail_nsw(
1935 ; CHECK-NEXT: entry:
1936 ; CHECK-NEXT: [[N_SUB:%.*]] = sub nsw i8 [[N:%.*]], [[N2:%.*]]
1937 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[N_SUB]], -31
1938 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1940 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
1942 ; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
1943 ; CHECK-NEXT: ret i8 [[R]]
1946 %n_sub = sub nsw i8 %n, %n2
1947 %cmp = icmp ule i8 %n_sub, 224
1948 br i1 %cmp, label %if.then, label %if.else
1959 define i8 @test_icmp_sub_fail_bad_range(i8 %n, i8 %n2, i8 %other) {
1960 ; CHECK-LABEL: @test_icmp_sub_fail_bad_range(
1961 ; CHECK-NEXT: entry:
1962 ; CHECK-NEXT: [[N_SUB:%.*]] = sub nuw i8 [[N:%.*]], [[N2:%.*]]
1963 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[N_SUB]], -34
1964 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1966 ; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
1967 ; CHECK-NEXT: ret i8 [[R]]
1969 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
1972 %n_sub = sub nuw i8 %n, %n2
1973 %cmp = icmp uge i8 %n_sub, 223
1974 br i1 %cmp, label %if.then, label %if.else
1984 define i8 @test_icmp_sub_fail_bad_pred(i8 %n, i8 %n2, i8 %other) {
1985 ; CHECK-LABEL: @test_icmp_sub_fail_bad_pred(
1986 ; CHECK-NEXT: entry:
1987 ; CHECK-NEXT: [[N_SUB:%.*]] = sub nuw i8 [[N:%.*]], [[N2:%.*]]
1988 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[N_SUB]], 31
1989 ; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1991 ; CHECK-NEXT: [[R:%.*]] = and i8 [[N]], 32
1992 ; CHECK-NEXT: ret i8 [[R]]
1994 ; CHECK-NEXT: ret i8 [[OTHER:%.*]]
1997 %n_sub = sub nuw i8 %n, %n2
1998 %cmp = icmp sge i8 %n_sub, 32
1999 br i1 %cmp, label %if.then, label %if.else
2009 define i8 @simplifydemanded_context(i8 %x, i8 %y) {
2010 ; CHECK-LABEL: @simplifydemanded_context(
2011 ; CHECK-NEXT: call void @dummy()
2012 ; CHECK-NEXT: [[X_LOBITS:%.*]] = and i8 [[X:%.*]], 3
2013 ; CHECK-NEXT: [[PRECOND:%.*]] = icmp eq i8 [[X_LOBITS]], 0
2014 ; CHECK-NEXT: call void @llvm.assume(i1 [[PRECOND]])
2015 ; CHECK-NEXT: ret i8 0
2017 %and1 = and i8 %x, 1
2018 call void @dummy() ; may unwind
2019 %x.lobits = and i8 %x, 3
2020 %precond = icmp eq i8 %x.lobits, 0
2021 call void @llvm.assume(i1 %precond)
2022 %and2 = and i8 %and1, %y
2026 define i16 @pr97330(i1 %c, ptr %p1, ptr %p2) {
2027 ; CHECK-LABEL: @pr97330(
2028 ; CHECK-NEXT: entry:
2029 ; CHECK-NEXT: br i1 [[C:%.*]], label [[EXIT:%.*]], label [[IF:%.*]]
2031 ; CHECK-NEXT: unreachable
2033 ; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[P1:%.*]], align 8
2034 ; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[V]] to i16
2035 ; CHECK-NEXT: ret i16 [[CONV]]
2038 %v = load i64, ptr %p1, align 8
2039 %conv = trunc i64 %v to i16
2040 br i1 %c, label %exit, label %if
2043 %cmp = icmp ne i16 %conv, 1
2044 %conv2 = zext i1 %cmp to i32
2045 store i32 %conv2, ptr %p2, align 4
2046 %cmp2 = icmp eq i64 %v, 1
2047 call void @llvm.assume(i1 %cmp2)
2054 define i1 @mul_nuw_nsw_nonneg_const(i8 %x) {
2055 ; CHECK-LABEL: @mul_nuw_nsw_nonneg_const(
2056 ; CHECK-NEXT: ret i1 true
2058 %mul = mul nuw nsw i8 %x, 3
2059 %cmp = icmp sgt i8 %mul, -1
2063 define i1 @mul_nuw_nsw_nonneg_const_missing_nuw(i8 %x) {
2064 ; CHECK-LABEL: @mul_nuw_nsw_nonneg_const_missing_nuw(
2065 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
2066 ; CHECK-NEXT: ret i1 [[CMP]]
2068 %mul = mul nsw i8 %x, 3
2069 %cmp = icmp sgt i8 %mul, -1
2073 define i1 @mul_nuw_nsw_nonneg_const_missing_nsw(i8 %x) {
2074 ; CHECK-LABEL: @mul_nuw_nsw_nonneg_const_missing_nsw(
2075 ; CHECK-NEXT: [[MUL:%.*]] = mul nuw i8 [[X:%.*]], 3
2076 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[MUL]], -1
2077 ; CHECK-NEXT: ret i1 [[CMP]]
2079 %mul = mul nuw i8 %x, 3
2080 %cmp = icmp sgt i8 %mul, -1
2084 define i1 @mul_nuw_nsw_nonneg_can_be_one(i8 %x, i8 %y) {
2085 ; CHECK-LABEL: @mul_nuw_nsw_nonneg_can_be_one(
2086 ; CHECK-NEXT: [[Y_NNEG:%.*]] = and i8 [[Y:%.*]], 127
2087 ; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y_NNEG]]
2088 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[MUL]], -1
2089 ; CHECK-NEXT: ret i1 [[CMP]]
2091 %y.nneg = and i8 %y, 127
2092 %mul = mul nuw nsw i8 %x, %y.nneg
2093 %cmp = icmp sgt i8 %mul, -1
2097 define i1 @mul_nuw_nsw_nonneg_cant_be_one(i8 %x, i8 %y) {
2098 ; CHECK-LABEL: @mul_nuw_nsw_nonneg_cant_be_one(
2099 ; CHECK-NEXT: ret i1 true
2101 %y.nneg = and i8 %y, 127
2102 %y.nneg.not.one = or i8 %y.nneg, 2
2103 %mul = mul nuw nsw i8 %x, %y.nneg.not.one
2104 %cmp = icmp sgt i8 %mul, -1
2108 define i1 @mul_nuw_nsw_nonneg_cant_be_one_commuted(i8 %x, i8 %y) {
2109 ; CHECK-LABEL: @mul_nuw_nsw_nonneg_cant_be_one_commuted(
2110 ; CHECK-NEXT: ret i1 true
2112 %y.nneg = and i8 %y, 127
2113 %y.nneg.not.one = or i8 %y.nneg, 2
2114 %mul = mul nuw nsw i8 %y.nneg.not.one, %x
2115 %cmp = icmp sgt i8 %mul, -1
2119 declare void @dummy()
2120 declare void @use(i1)
2121 declare void @sink(i8)