Revert "[InstCombine] Support gep nuw in icmp folds" (#118698)
[llvm-project.git] / llvm / test / Transforms / InstCombine / known-bits.ll
blob9467f507cd6306d0dd2f10182c317fae341f5c97
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)
7 ; CHECK-NEXT:    ret void
9   %y = zext i1 %x to i8
10   %z = shl i8 64, %y
11   %a = and i8 %z, 1
12   call void @sink(i8 %a)
13   ret void
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
21   %y = zext i1 %x to i8
22   %z = lshr i8 64, %y
23   %a = and i8 %z, 1
24   call void @sink(i8 %a)
25   ret void
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
33   %y = zext i1 %x to i8
34   %z = ashr i8 -16, %y
35   %a = and i8 %z, 3
36   call void @sink(i8 %a)
37   ret void
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
45   %y = udiv i8 10, %x
46   %z = and i8 %y, 64
47   call void @sink(i8 %z)
48   ret void
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:%.*]]
56 ; CHECK:       if:
57 ; CHECK-NEXT:    ret i8 -4
58 ; CHECK:       exit:
59 ; CHECK-NEXT:    [[OR2:%.*]] = or i8 [[X]], -4
60 ; CHECK-NEXT:    ret i8 [[OR2]]
62   %and = and i8 %x, 3
63   %cmp = icmp eq i8 %and, 0
64   br i1 %cmp, label %if, label %exit
66 if:
67   %or1 = or i8 %x, -4
68   ret i8 %or1
70 exit:
71   %or2 = or i8 %x, -4
72   ret i8 %or2
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:%.*]]
81 ; CHECK:       if:
82 ; CHECK-NEXT:    ret i8 -4
83 ; CHECK:       exit:
84 ; CHECK-NEXT:    [[OR2:%.*]] = or i8 [[X]], -4
85 ; CHECK-NEXT:    ret i8 [[OR2]]
87   %and = and i8 %x, 3
88   %cmp = icmp ne i8 %and, 0
89   call void @use(i1 %cmp)
90   br i1 %cmp, label %exit, label %if
92 if:
93   %or1 = or i8 %x, -4
94   ret i8 %or1
96 exit:
97   %or2 = or i8 %x, -4
98   ret i8 %or2
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:%.*]]
107 ; CHECK:       if:
108 ; CHECK-NEXT:    ret i8 -4
109 ; CHECK:       exit:
110 ; CHECK-NEXT:    [[OR2:%.*]] = or i8 [[X]], -4
111 ; CHECK-NEXT:    ret i8 [[OR2]]
113   %and = and i8 %x, 3
114   %cmp = icmp eq i8 %and, 0
115   %cond = and i1 %cmp, %c
116   br i1 %cond, label %if, label %exit
119   %or1 = or i8 %x, -4
120   ret i8 %or1
122 exit:
123   %or2 = or i8 %x, -4
124   ret i8 %or2
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:%.*]]
134 ; CHECK:       if:
135 ; CHECK-NEXT:    [[OR1:%.*]] = or i8 [[X]], -4
136 ; CHECK-NEXT:    ret i8 [[OR1]]
137 ; CHECK:       exit:
138 ; CHECK-NEXT:    ret i8 -4
140   %and = and i8 %x, 91
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
147   %or1 = or i8 %x, -4
148   ret i8 %or1
150 exit:
151   %or2 = or i8 %x, -4
152   ret i8 %or2
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:%.*]]
162 ; CHECK:       if:
163 ; CHECK-NEXT:    ret i8 -4
164 ; CHECK:       exit:
165 ; CHECK-NEXT:    [[OR2:%.*]] = or i8 [[X]], -4
166 ; CHECK-NEXT:    ret i8 [[OR2]]
168   %and = and i8 %x, 91
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
175   %or1 = or i8 %x, -4
176   ret i8 %or1
178 exit:
179   %or2 = or i8 %x, -4
180   ret i8 %or2
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:%.*]]
190 ; CHECK:       if:
191 ; CHECK-NEXT:    ret i8 -4
192 ; CHECK:       exit:
193 ; CHECK-NEXT:    [[OR2:%.*]] = or i8 [[X]], -4
194 ; CHECK-NEXT:    ret i8 [[OR2]]
196   %and = and i8 %x, 3
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
203   %or1 = or i8 %x, -4
204   ret i8 %or1
206 exit:
207   %or2 = or i8 %x, -4
208   ret i8 %or2
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:%.*]]
217 ; CHECK:       if:
218 ; CHECK-NEXT:    ret i8 -4
219 ; CHECK:       exit:
220 ; CHECK-NEXT:    [[OR2:%.*]] = or i8 [[X]], -4
221 ; CHECK-NEXT:    ret i8 [[OR2]]
223   %and = and i8 %x, 3
224   %cmp = icmp eq i8 %and, 0
225   %cond = select i1 %cmp, i1 %c, i1 false
226   br i1 %cond, label %if, label %exit
229   %or1 = or i8 %x, -4
230   ret i8 %or1
232 exit:
233   %or2 = or i8 %x, -4
234   ret i8 %or2
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:%.*]]
243 ; CHECK:       if:
244 ; CHECK-NEXT:    [[OR1:%.*]] = or i8 [[X]], -4
245 ; CHECK-NEXT:    ret i8 [[OR1]]
246 ; CHECK:       exit:
247 ; CHECK-NEXT:    [[OR2:%.*]] = or i8 [[X]], -4
248 ; CHECK-NEXT:    ret i8 [[OR2]]
250   %and = and i8 %x, 3
251   %cmp = icmp eq i8 %and, 0
252   %cond = or i1 %cmp, %c
253   br i1 %cond, label %if, label %exit
256   %or1 = or i8 %x, -4
257   ret i8 %or1
259 exit:
260   %or2 = or i8 %x, -4
261   ret i8 %or2
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:%.*]]
270 ; CHECK:       if:
271 ; CHECK-NEXT:    [[OR1:%.*]] = or i8 [[X]], -4
272 ; CHECK-NEXT:    ret i8 [[OR1]]
273 ; CHECK:       exit:
274 ; CHECK-NEXT:    ret i8 -4
276   %and = and i8 %x, 3
277   %cmp = icmp ne i8 %and, 0
278   %cond = or i1 %cmp, %c
279   br i1 %cond, label %if, label %exit
282   %or1 = or i8 %x, -4
283   ret i8 %or1
285 exit:
286   %or2 = or i8 %x, -4
287   ret i8 %or2
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:%.*]]
296 ; CHECK:       if:
297 ; CHECK-NEXT:    ret i8 -4
298 ; CHECK:       exit:
299 ; CHECK-NEXT:    [[OR2:%.*]] = or i8 [[X]], -4
300 ; CHECK-NEXT:    ret i8 [[OR2]]
302   %and = and i8 %x, 3
303   %cmp = icmp ne i8 %and, 0
304   %cond = select i1 %cmp, i1 false, i1 %c
305   br i1 %cond, label %if, label %exit
308   %or1 = or i8 %x, -4
309   ret i8 %or1
311 exit:
312   %or2 = or i8 %x, -4
313   ret i8 %or2
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:%.*]]
322 ; CHECK:       if:
323 ; CHECK-NEXT:    [[OR1:%.*]] = or i8 [[X]], -4
324 ; CHECK-NEXT:    ret i8 [[OR1]]
325 ; CHECK:       exit:
326 ; CHECK-NEXT:    [[OR2:%.*]] = or i8 [[X]], -4
327 ; CHECK-NEXT:    ret i8 [[OR2]]
329   %and = and i8 %x, 3
330   %cmp = icmp ne i8 %and, 0
331   %cond = and i1 %cmp, %c
332   br i1 %cond, label %if, label %exit
335   %or1 = or i8 %x, -4
336   ret i8 %or1
338 exit:
339   %or2 = or i8 %x, -4
340   ret i8 %or2
343 define i32 @test_icmp_trunc1(i32 %x) {
344 ; CHECK-LABEL: @test_icmp_trunc1(
345 ; CHECK-NEXT:  entry:
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:%.*]]
349 ; CHECK:       then:
350 ; CHECK-NEXT:    ret i32 7
351 ; CHECK:       else:
352 ; CHECK-NEXT:    ret i32 0
354 entry:
355   %y = trunc i32 %x to i16
356   %cmp = icmp eq i16 %y, 7
357   br i1 %cmp, label %then, label %else
358 then:
359   %z = and i32 %x, 15
360   ret i32 %z
361 else:
362   ret i32 0
365 define i32 @test_icmp_trunc_assume(i32 %x) {
366 ; CHECK-LABEL: @test_icmp_trunc_assume(
367 ; CHECK-NEXT:  entry:
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
373 entry:
374   %y = trunc i32 %x to i16
375   %cmp = icmp eq i16 %y, 7
376   call void @llvm.assume(i1 %cmp)
377   %z = and i32 %x, 15
378   ret i32 %z
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:%.*]]
386 ; CHECK:       if.then:
387 ; CHECK-NEXT:    [[SEXT:%.*]] = and i64 [[X]], 2147483647
388 ; CHECK-NEXT:    ret i64 [[SEXT]]
389 ; CHECK:       if.else:
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
396 if.then:
397   %sext = shl i64 %x, 32
398   %ret = ashr exact i64 %sext, 32
399   ret i64 %ret
400 if.else:
401   ret i64 0
404 define i64 @test_icmp_trunc3(i64 %n) {
405 ; CHECK-LABEL: @test_icmp_trunc3(
406 ; CHECK-NEXT:  entry:
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:%.*]]
410 ; CHECK:       if.then:
411 ; CHECK-NEXT:    [[RET:%.*]] = and i64 [[N]], 127
412 ; CHECK-NEXT:    ret i64 [[RET]]
413 ; CHECK:       if.else:
414 ; CHECK-NEXT:    ret i64 0
416 entry:
417   %conv = trunc i64 %n to i32
418   %cmp = icmp ult i32 %conv, 96
419   br i1 %cmp, label %if.then, label %if.else
421 if.then:
422   %ret = and i64 %n, 4294967295
423   ret i64 %ret
425 if.else:
426   ret i64 0
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:%.*]]
434 ; CHECK:       if.then:
435 ; CHECK-NEXT:    [[CONV2:%.*]] = trunc i64 [[N]] to i8
436 ; CHECK-NEXT:    [[ADD:%.*]] = or disjoint i8 [[CONV2]], 48
437 ; CHECK-NEXT:    ret i8 [[ADD]]
438 ; CHECK:       if.else:
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
445 if.then:
446   %conv2 = trunc i64 %n to i8
447   %add = add i8 %conv2, 48
448   ret i8 %add
450 if.else:
451   ret i8 0
454 define i64 @test_icmp_trunc5(i64 %n) {
455 ; CHECK-LABEL: @test_icmp_trunc5(
456 ; CHECK-NEXT:  entry:
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:%.*]]
461 ; CHECK:       if.then:
462 ; CHECK-NEXT:    [[TMP0:%.*]] = and i64 [[SHR]], 15
463 ; CHECK-NEXT:    [[NOT:%.*]] = xor i64 [[TMP0]], 15
464 ; CHECK-NEXT:    ret i64 [[NOT]]
465 ; CHECK:       if.else:
466 ; CHECK-NEXT:    ret i64 13
468 entry:
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
474 if.then:
475   %and = and i64 %shr, 4294967295
476   %not = xor i64 %and, 4294967295
477   ret i64 %not
479 if.else:
480   ret i64 13
483 define i1 @test_icmp_or_distjoint(i8 %n, i1 %other) {
484 ; CHECK-LABEL: @test_icmp_or_distjoint(
485 ; CHECK-NEXT:  entry:
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:%.*]]
489 ; CHECK:       if.then:
490 ; CHECK-NEXT:    ret i1 true
491 ; CHECK:       if.else:
492 ; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
494 entry:
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
499 if.then:
500   %r = icmp slt i8 %n, 0
501   ret i1 %r
503 if.else:
504   ret i1 %other
507 define i1 @test_icmp_or_fail_missing_disjoint(i8 %n, i1 %other) {
508 ; CHECK-LABEL: @test_icmp_or_fail_missing_disjoint(
509 ; CHECK-NEXT:  entry:
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:%.*]]
513 ; CHECK:       if.then:
514 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[N]], 0
515 ; CHECK-NEXT:    ret i1 [[R]]
516 ; CHECK:       if.else:
517 ; CHECK-NEXT:    ret i1 [[OTHER:%.*]]
519 entry:
520   %n_or = or i8 %n, 16
521   %cmp = icmp ugt i8 %n_or, 145
522   br i1 %cmp, label %if.then, label %if.else
524 if.then:
525   %r = icmp slt i8 %n, 0
526   ret i1 %r
528 if.else:
529   ret i1 %other
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
539   %xy = and i8 %x, %y
540   %cmp = icmp eq i8 %xy, 123
541   call void @llvm.assume(i1 %cmp)
542   %r = and i8 %x, 1
543   ret i8 %r
546 define i8 @test_icmp_or(i8 %n, i8 %n2, i8 %other) {
547 ; CHECK-LABEL: @test_icmp_or(
548 ; CHECK-NEXT:  entry:
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:%.*]]
552 ; CHECK:       if.then:
553 ; CHECK-NEXT:    ret i8 0
554 ; CHECK:       if.else:
555 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
557 entry:
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
562 if.then:
563   %r = and i8 %n, 32
564   ret i8 %r
566 if.else:
567   ret i8 %other
570 define i8 @test_icmp_or2(i8 %n, i8 %n2, i8 %other) {
571 ; CHECK-LABEL: @test_icmp_or2(
572 ; CHECK-NEXT:  entry:
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:%.*]]
576 ; CHECK:       if.then:
577 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
578 ; CHECK:       if.else:
579 ; CHECK-NEXT:    ret i8 0
581 entry:
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
586 if.then:
587   ret i8 %other
588 if.else:
589   %r = and i8 %n, 32
590   ret i8 %r
594 define i8 @test_icmp_or_fail_bad_range(i8 %n, i8 %n2, i8 %other) {
595 ; CHECK-LABEL: @test_icmp_or_fail_bad_range(
596 ; CHECK-NEXT:  entry:
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:%.*]]
600 ; CHECK:       if.then:
601 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[N]], 32
602 ; CHECK-NEXT:    ret i8 [[R]]
603 ; CHECK:       if.else:
604 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
606 entry:
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
611 if.then:
612   %r = and i8 %n, 32
613   ret i8 %r
615 if.else:
616   ret i8 %other
619 define i8 @test_icmp_or_fail_bad_pred(i8 %n, i8 %n2, i8 %other) {
620 ; CHECK-LABEL: @test_icmp_or_fail_bad_pred(
621 ; CHECK-NEXT:  entry:
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:%.*]]
625 ; CHECK:       if.then:
626 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[N]], 32
627 ; CHECK-NEXT:    ret i8 [[R]]
628 ; CHECK:       if.else:
629 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
631 entry:
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
636 if.then:
637   %r = and i8 %n, 32
638   ret i8 %r
640 if.else:
641   ret i8 %other
644 define i8 @test_icmp_and(i8 %n, i8 %n2, i8 %other) {
645 ; CHECK-LABEL: @test_icmp_and(
646 ; CHECK-NEXT:  entry:
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:%.*]]
650 ; CHECK:       if.then:
651 ; CHECK-NEXT:    ret i8 32
652 ; CHECK:       if.else:
653 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
655 entry:
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
660 if.then:
661   %r = and i8 %n, 32
662   ret i8 %r
664 if.else:
665   ret i8 %other
668 define i8 @test_icmp_and2(i8 %n, i8 %n2, i8 %other) {
669 ; CHECK-LABEL: @test_icmp_and2(
670 ; CHECK-NEXT:  entry:
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:%.*]]
674 ; CHECK:       if.then:
675 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
676 ; CHECK:       if.else:
677 ; CHECK-NEXT:    ret i8 32
679 entry:
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
684 if.then:
685   ret i8 %other
686 if.else:
687   %r = and i8 %n, 32
688   ret i8 %r
692 define i8 @test_icmp_and_fail_bad_range(i8 %n, i8 %n2, i8 %other) {
693 ; CHECK-LABEL: @test_icmp_and_fail_bad_range(
694 ; CHECK-NEXT:  entry:
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:%.*]]
698 ; CHECK:       if.then:
699 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[N]], 32
700 ; CHECK-NEXT:    ret i8 [[R]]
701 ; CHECK:       if.else:
702 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
704 entry:
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
709 if.then:
710   %r = and i8 %n, 32
711   ret i8 %r
713 if.else:
714   ret i8 %other
717 define i8 @test_icmp_and_fail_bad_pred(i8 %n, i8 %n2, i8 %other) {
718 ; CHECK-LABEL: @test_icmp_and_fail_bad_pred(
719 ; CHECK-NEXT:  entry:
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:%.*]]
723 ; CHECK:       if.then:
724 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[N]], 32
725 ; CHECK-NEXT:    ret i8 [[R]]
726 ; CHECK:       if.else:
727 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
729 entry:
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
734 if.then:
735   %r = and i8 %n, 32
736   ret i8 %r
738 if.else:
739   ret i8 %other
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
749   %xy = and i8 %x, %y
750   %cmp = icmp eq i8 %xy, 123
751   call void @llvm.assume(i1 %cmp)
752   %r = and i8 %y, 11
753   ret i8 %r
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]]
764   %xy = and i8 %x, %y
765   %cmp = icmp eq i8 %xy, 123
766   call void @llvm.assume(i1 %cmp)
767   %r = and i8 %y, 111
768   ret i8 %r
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
778   %xy = or i8 %x, %y
779   %cmp = icmp eq i8 %xy, 124
780   call void @llvm.assume(i1 %cmp)
781   %r = and i8 %x, 3
782   ret i8 %r
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
792   %xy = or i8 %x, %y
793   %cmp = icmp eq i8 %xy, 124
794   call void @llvm.assume(i1 %cmp)
795   %r = and i8 %y, 1
796   ret i8 %r
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]]
807   %xy = or i8 %x, %y
808   %cmp = icmp eq i8 %xy, 124
809   call void @llvm.assume(i1 %cmp)
810   %r = and i8 %y, 7
811   ret i8 %r
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]]
822   %xy = or i8 %x, %y
823   %cmp = icmp ne i8 %xy, 124
824   call void @llvm.assume(i1 %cmp)
825   %r = and i8 %x, 3
826   ret i8 %r
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
856   ret i1 %r
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
881   ret i1 %r
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
909   ret i1 %r
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
937   ret i1 %r
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
965   ret i1 %r
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
993   ret i1 %r
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]]
1007   %x = add i8 %xx, 1
1008   %y = add i8 %yy, 1
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
1015   ret i1 %r
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
1030   %y = add i8 %x, %z
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
1038   ret i1 %r
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]]
1052   %y = add i8 %x, %z
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
1059   ret i1 %r
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
1074   %y = add i8 %x, %z
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
1082   ret i1 %r
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
1101   ret i1 %r
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
1115   %x = or i8 %xx, 1
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
1124   ret i1 %r
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]]
1139   %x = or i8 %xx, 2
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
1148   ret i1 %r
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
1162   %x = or i8 %xx, 1
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
1171   ret i1 %r
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]]
1186   %x = or i8 %xx, 1
1187   %y = add i8 %yy, 1
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
1195   ret i1 %r
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)
1204   %r = and i8 %v, 1
1205   ret i8 %r
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)
1217   %r = and i8 %v, 4
1218   ret i8 %r
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)
1227   %r = and i8 %v, 1
1228   ret i8 %r
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)
1240   %r = and i8 %v, 2
1241   ret i8 %r
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)
1250   %r = and i8 %v, 1
1251   ret i8 %r
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)
1260   %r = and i8 %v, 16
1261   ret i8 %r
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)
1273   %r = and i8 %v, 2
1274   ret i8 %r
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)
1283   %r = and i8 %v, 1
1284   ret i8 %r
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)
1293   %r = and i8 %v, 32
1294   ret i8 %r
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)
1306   %r = and i8 %v, 16
1307   ret i8 %r
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)
1319   %r = and i8 %v, 2
1320   ret i8 %r
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)
1331   %r = and i8 %v, 1
1332   ret i8 %r
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)
1346   %r = and i8 %v, 1
1347   ret i8 %r
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)
1361   %r = and i8 %v, 2
1362   ret i8 %r
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)
1373   %r = and i8 %v, 2
1374   ret i8 %r
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
1384   ret i1 %sign
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
1394   ret i1 %sign
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
1407   ret i1 %sign
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
1418   ret i1 %sign
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
1428   ret <2 x i1> %sign
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
1437   ret i32 %and
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
1446   ret i16 %and
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
1455   ret i128 %and
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
1464   ret i32 %and
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
1473   ret i80 %and
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
1484   ret i32 %and
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
1495   ret i32 %and
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
1506   ret i32 %and
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:%.*]]
1514 ; CHECK:       if.then:
1515 ; CHECK-NEXT:    ret i32 0
1516 ; CHECK:       if.else:
1517 ; CHECK-NEXT:    ret i32 0
1519   %cmp = fcmp oeq double %x, 0xFFF0000000000000
1520   br i1 %cmp, label %if.then, label %if.else
1522 if.then:
1523   %cast = bitcast double %x to i64
1524   %trunc = trunc i64 %cast to i32
1525   ret i32 %trunc
1527 if.else:
1528   ret i32 0
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
1539   ret i1 %cmp
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
1550   ret i32 %masked
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
1561   ret i32 %masked
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
1572   ret i32 %masked
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
1583   ret i32 %masked
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:%.*]]
1591 ; CHECK:       if.end:
1592 ; CHECK-NEXT:    ret i16 31744
1593 ; CHECK:       if.else:
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
1600 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
1606   ret i16 %or
1608 if.else:
1609   ret i16 0
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:%.*]]
1619 ; CHECK:       if.then:
1620 ; CHECK-NEXT:    [[CAST:%.*]] = bitcast double [[X]] to i64
1621 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[CAST]], 3458764513820540928
1622 ; CHECK-NEXT:    ret i1 [[CMP]]
1623 ; CHECK:       if.else:
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
1630 if.then:
1631   %cast = bitcast double %x to i64
1632   %cmp = icmp eq i64 %cast, 3458764513820540928
1633   ret i1 %cmp
1635 if.else:
1636   ret i1 false
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
1647   ret i32 %and
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
1658   ret i32 %and
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:%.*]]
1666 ; CHECK:       if.then1:
1667 ; CHECK-NEXT:    br i1 true, label [[IF_ELSE]], label [[IF_THEN2:%.*]]
1668 ; CHECK:       if.then2:
1669 ; CHECK-NEXT:    ret i64 poison
1670 ; CHECK:       if.else:
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
1676 if.then1:
1677   br i1 %cmp, label %if.else, label %if.then2
1679 if.then2:
1680   %cast = bitcast double %x to i64
1681   %and = and i64 %cast, 1
1682   ret i64 %and
1684 if.else:
1685   ret i64 0
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
1696   ret i32 %and
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
1711   ret i1 %cmp
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
1724   ret i1 %cmp
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
1734   ret i1 %cmp
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:%.*]]
1743 ; CHECK:       if.then:
1744 ; CHECK-NEXT:    ret i8 0
1745 ; CHECK:       if.else:
1746 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
1748 entry:
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
1753 if.then:
1754   %r = and i8 %n, 32
1755   ret i8 %r
1757 if.else:
1758   ret i8 %other
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:%.*]]
1767 ; CHECK:       if.then:
1768 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[N]], 32
1769 ; CHECK-NEXT:    ret i8 [[R]]
1770 ; CHECK:       if.else:
1771 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
1773 entry:
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
1778 if.then:
1779   %r = and i8 %n, 32
1780   ret i8 %r
1782 if.else:
1783   ret i8 %other
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:%.*]]
1792 ; CHECK:       if.then:
1793 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
1794 ; CHECK:       if.else:
1795 ; CHECK-NEXT:    ret i8 0
1797 entry:
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
1802 if.then:
1803   ret i8 %other
1804 if.else:
1805   %r = and i8 %n, 32
1806   ret i8 %r
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:%.*]]
1816 ; CHECK:       if.then:
1817 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[N]], 32
1818 ; CHECK-NEXT:    ret i8 [[R]]
1819 ; CHECK:       if.else:
1820 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
1822 entry:
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
1827 if.then:
1828   %r = and i8 %n, 32
1829   ret i8 %r
1831 if.else:
1832   ret i8 %other
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:%.*]]
1841 ; CHECK:       if.then:
1842 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[N]], 32
1843 ; CHECK-NEXT:    ret i8 [[R]]
1844 ; CHECK:       if.else:
1845 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
1847 entry:
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
1852 if.then:
1853   %r = and i8 %n, 32
1854   ret i8 %r
1856 if.else:
1857   ret i8 %other
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:%.*]]
1866 ; CHECK:       if.then:
1867 ; CHECK-NEXT:    ret i8 32
1868 ; CHECK:       if.else:
1869 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
1871 entry:
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
1876 if.then:
1877   %r = and i8 %n, 32
1878   ret i8 %r
1880 if.else:
1881   ret i8 %other
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:%.*]]
1890 ; CHECK:       if.then:
1891 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[N2]], 32
1892 ; CHECK-NEXT:    ret i8 [[R]]
1893 ; CHECK:       if.else:
1894 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
1896 entry:
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
1901 if.then:
1902   %r = and i8 %n2, 32
1903   ret i8 %r
1905 if.else:
1906   ret i8 %other
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:%.*]]
1915 ; CHECK:       if.then:
1916 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
1917 ; CHECK:       if.else:
1918 ; CHECK-NEXT:    ret i8 32
1920 entry:
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
1925 if.then:
1926   ret i8 %other
1927 if.else:
1928   %r = and i8 %n, 32
1929   ret i8 %r
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:%.*]]
1939 ; CHECK:       if.then:
1940 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
1941 ; CHECK:       if.else:
1942 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[N]], 32
1943 ; CHECK-NEXT:    ret i8 [[R]]
1945 entry:
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
1950 if.then:
1951   ret i8 %other
1952 if.else:
1953   %r = and i8 %n, 32
1954   ret i8 %r
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:%.*]]
1965 ; CHECK:       if.then:
1966 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[N]], 32
1967 ; CHECK-NEXT:    ret i8 [[R]]
1968 ; CHECK:       if.else:
1969 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
1971 entry:
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
1976 if.then:
1977   %r = and i8 %n, 32
1978   ret i8 %r
1980 if.else:
1981   ret i8 %other
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:%.*]]
1990 ; CHECK:       if.then:
1991 ; CHECK-NEXT:    [[R:%.*]] = and i8 [[N]], 32
1992 ; CHECK-NEXT:    ret i8 [[R]]
1993 ; CHECK:       if.else:
1994 ; CHECK-NEXT:    ret i8 [[OTHER:%.*]]
1996 entry:
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
2001 if.then:
2002   %r = and i8 %n, 32
2003   ret i8 %r
2005 if.else:
2006   ret i8 %other
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
2023   ret i8 %and2
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:%.*]]
2030 ; CHECK:       if:
2031 ; CHECK-NEXT:    unreachable
2032 ; CHECK:       exit:
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]]
2037 entry:
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)
2048   unreachable
2050 exit:
2051   ret i16 %conv
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
2060   ret i1 %cmp
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
2070   ret i1 %cmp
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
2081   ret i1 %cmp
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
2094   ret i1 %cmp
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
2105   ret i1 %cmp
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
2116   ret i1 %cmp
2119 declare void @dummy()
2120 declare void @use(i1)
2121 declare void @sink(i8)