xref: /llvm-project/llvm/test/Transforms/InstCombine/known-bits.ll (revision 56c091ea7106507b36015297ee9005c9d5fab0bf)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3
4define void @test_shl(i1 %x) {
5; CHECK-LABEL: @test_shl(
6; CHECK-NEXT:    call void @sink(i8 0)
7; CHECK-NEXT:    ret void
8;
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
14}
15
16define void @test_lshr(i1 %x) {
17; CHECK-LABEL: @test_lshr(
18; CHECK-NEXT:    call void @sink(i8 0)
19; CHECK-NEXT:    ret void
20;
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
26}
27
28define void @test_ashr(i1 %x) {
29; CHECK-LABEL: @test_ashr(
30; CHECK-NEXT:    call void @sink(i8 0)
31; CHECK-NEXT:    ret void
32;
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
38}
39
40define void @test_udiv(i8 %x) {
41; CHECK-LABEL: @test_udiv(
42; CHECK-NEXT:    call void @sink(i8 0)
43; CHECK-NEXT:    ret void
44;
45  %y = udiv i8 10, %x
46  %z = and i8 %y, 64
47  call void @sink(i8 %z)
48  ret void
49}
50
51define 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]]
61;
62  %and = and i8 %x, 3
63  %cmp = icmp eq i8 %and, 0
64  br i1 %cmp, label %if, label %exit
65
66if:
67  %or1 = or i8 %x, -4
68  ret i8 %or1
69
70exit:
71  %or2 = or i8 %x, -4
72  ret i8 %or2
73}
74
75define 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]]
86;
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
91
92if:
93  %or1 = or i8 %x, -4
94  ret i8 %or1
95
96exit:
97  %or2 = or i8 %x, -4
98  ret i8 %or2
99}
100
101define 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]]
112;
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
117
118if:
119  %or1 = or i8 %x, -4
120  ret i8 %or1
121
122exit:
123  %or2 = or i8 %x, -4
124  ret i8 %or2
125}
126
127define 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
139;
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
145
146if:
147  %or1 = or i8 %x, -4
148  ret i8 %or1
149
150exit:
151  %or2 = or i8 %x, -4
152  ret i8 %or2
153}
154
155define 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]]
167;
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
173
174if:
175  %or1 = or i8 %x, -4
176  ret i8 %or1
177
178exit:
179  %or2 = or i8 %x, -4
180  ret i8 %or2
181}
182
183define 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]]
195;
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
201
202if:
203  %or1 = or i8 %x, -4
204  ret i8 %or1
205
206exit:
207  %or2 = or i8 %x, -4
208  ret i8 %or2
209}
210
211define 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]]
222;
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
227
228if:
229  %or1 = or i8 %x, -4
230  ret i8 %or1
231
232exit:
233  %or2 = or i8 %x, -4
234  ret i8 %or2
235}
236
237define 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]]
249;
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
254
255if:
256  %or1 = or i8 %x, -4
257  ret i8 %or1
258
259exit:
260  %or2 = or i8 %x, -4
261  ret i8 %or2
262}
263
264define 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
275;
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
280
281if:
282  %or1 = or i8 %x, -4
283  ret i8 %or1
284
285exit:
286  %or2 = or i8 %x, -4
287  ret i8 %or2
288}
289
290define 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]]
301;
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
306
307if:
308  %or1 = or i8 %x, -4
309  ret i8 %or1
310
311exit:
312  %or2 = or i8 %x, -4
313  ret i8 %or2
314}
315
316define 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]]
328;
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
333
334if:
335  %or1 = or i8 %x, -4
336  ret i8 %or1
337
338exit:
339  %or2 = or i8 %x, -4
340  ret i8 %or2
341}
342
343define 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
353;
354entry:
355  %y = trunc i32 %x to i16
356  %cmp = icmp eq i16 %y, 7
357  br i1 %cmp, label %then, label %else
358then:
359  %z = and i32 %x, 15
360  ret i32 %z
361else:
362  ret i32 0
363}
364
365define 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
372;
373entry:
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
379}
380
381define 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
391;
392  %conv = trunc i64 %x to i32
393  %cmp = icmp sgt i32 %conv, 12
394  br i1 %cmp, label %if.then, label %if.else
395
396if.then:
397  %sext = shl i64 %x, 32
398  %ret = ashr exact i64 %sext, 32
399  ret i64 %ret
400if.else:
401  ret i64 0
402}
403
404define 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
415;
416entry:
417  %conv = trunc i64 %n to i32
418  %cmp = icmp ult i32 %conv, 96
419  br i1 %cmp, label %if.then, label %if.else
420
421if.then:
422  %ret = and i64 %n, 4294967295
423  ret i64 %ret
424
425if.else:
426  ret i64 0
427}
428
429define 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
440;
441  %conv = trunc i64 %n to i32
442  %cmp = icmp ult i32 %conv, 10
443  br i1 %cmp, label %if.then, label %if.else
444
445if.then:
446  %conv2 = trunc i64 %n to i8
447  %add = add i8 %conv2, 48
448  ret i8 %add
449
450if.else:
451  ret i8 0
452}
453
454define 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
467;
468entry:
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
473
474if.then:
475  %and = and i64 %shr, 4294967295
476  %not = xor i64 %and, 4294967295
477  ret i64 %not
478
479if.else:
480  ret i64 13
481}
482
483define 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:%.*]]
493;
494entry:
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
498
499if.then:
500  %r = icmp slt i8 %n, 0
501  ret i1 %r
502
503if.else:
504  ret i1 %other
505}
506
507define 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:%.*]]
518;
519entry:
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
523
524if.then:
525  %r = icmp slt i8 %n, 0
526  ret i1 %r
527
528if.else:
529  ret i1 %other
530}
531
532define 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
538;
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
544}
545
546define 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:%.*]]
556;
557entry:
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
561
562if.then:
563  %r = and i8 %n, 32
564  ret i8 %r
565
566if.else:
567  ret i8 %other
568}
569
570define 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
580;
581entry:
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
585
586if.then:
587  ret i8 %other
588if.else:
589  %r = and i8 %n, 32
590  ret i8 %r
591
592}
593
594define 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:%.*]]
605;
606entry:
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
610
611if.then:
612  %r = and i8 %n, 32
613  ret i8 %r
614
615if.else:
616  ret i8 %other
617}
618
619define 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:%.*]]
630;
631entry:
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
635
636if.then:
637  %r = and i8 %n, 32
638  ret i8 %r
639
640if.else:
641  ret i8 %other
642}
643
644define 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:%.*]]
654;
655entry:
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
659
660if.then:
661  %r = and i8 %n, 32
662  ret i8 %r
663
664if.else:
665  ret i8 %other
666}
667
668define 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
678;
679entry:
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
683
684if.then:
685  ret i8 %other
686if.else:
687  %r = and i8 %n, 32
688  ret i8 %r
689
690}
691
692define 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:%.*]]
703;
704entry:
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
708
709if.then:
710  %r = and i8 %n, 32
711  ret i8 %r
712
713if.else:
714  ret i8 %other
715}
716
717define 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:%.*]]
728;
729entry:
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
733
734if.then:
735  %r = and i8 %n, 32
736  ret i8 %r
737
738if.else:
739  ret i8 %other
740}
741
742define 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
748;
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
754}
755
756define 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]]
763;
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
769}
770
771define 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
777;
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
783}
784
785define 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
791;
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
797}
798
799define 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]]
806;
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
812}
813
814define 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]]
821;
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
827}
828
829declare void @use.i1(i1)
830declare void @use.i8(i8)
831
832declare void @use.2xi1(<2 x i1>)
833
834define 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
844;
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>
849
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
857}
858
859define 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
869;
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>
874
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
882}
883
884define 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]]
897;
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>
902
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
910}
911
912define 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]]
925;
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>
930
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
938}
939
940define 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]]
953;
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>
958
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
966}
967
968define 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
980;
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)
987
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
994}
995
996define 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]]
1006;
1007  %x = add i8 %xx, 1
1008  %y = add i8 %yy, 1
1009
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
1016}
1017
1018define 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
1028;
1029  %z = add nuw i8 %zz, 1
1030  %y = add i8 %x, %z
1031
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
1039}
1040
1041define 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]]
1051;
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
1060}
1061
1062define 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
1072;
1073  %z = add nuw i8 %zz, 1
1074  %y = add i8 %x, %z
1075
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
1083}
1084
1085define 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]]
1094;
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
1102}
1103
1104define 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
1114;
1115  %x = or i8 %xx, 1
1116  %y = add nuw i8 %yy, 1
1117
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
1125}
1126
1127define 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]]
1138;
1139  %x = or i8 %xx, 2
1140  %y = add nuw i8 %yy, 1
1141
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
1149}
1150
1151define 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
1161;
1162  %x = or i8 %xx, 1
1163  %y = add nuw i8 %yy, 1
1164
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
1172}
1173
1174define 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]]
1185;
1186  %x = or i8 %xx, 1
1187  %y = add i8 %yy, 1
1188
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
1196}
1197
1198define i8 @known_reduce_or(<2 x i8> %xx) {
1199; CHECK-LABEL: @known_reduce_or(
1200; CHECK-NEXT:    ret i8 1
1201;
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
1206}
1207
1208define 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]]
1214;
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
1219}
1220
1221define i8 @known_reduce_and(<2 x i8> %xx) {
1222; CHECK-LABEL: @known_reduce_and(
1223; CHECK-NEXT:    ret i8 1
1224;
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
1229}
1230
1231define 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]]
1237;
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
1242}
1243
1244define i8 @known_reduce_xor_even(<2 x i8> %xx) {
1245; CHECK-LABEL: @known_reduce_xor_even(
1246; CHECK-NEXT:    ret i8 0
1247;
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
1252}
1253
1254define i8 @known_reduce_xor_even2(<2 x i8> %xx) {
1255; CHECK-LABEL: @known_reduce_xor_even2(
1256; CHECK-NEXT:    ret i8 0
1257;
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
1262}
1263
1264define 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]]
1270;
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
1275}
1276
1277define i8 @known_reduce_xor_odd(<3 x i8> %xx) {
1278; CHECK-LABEL: @known_reduce_xor_odd(
1279; CHECK-NEXT:    ret i8 1
1280;
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
1285}
1286
1287define i8 @known_reduce_xor_odd2(<3 x i8> %xx) {
1288; CHECK-LABEL: @known_reduce_xor_odd2(
1289; CHECK-NEXT:    ret i8 0
1290;
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
1295}
1296
1297define 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]]
1303;
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
1308}
1309
1310define 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]]
1316;
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
1321}
1322
1323define 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
1326;
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
1333}
1334
1335define 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]]
1341;
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
1348}
1349
1350define 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]]
1356;
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
1363}
1364
1365define 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
1368;
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
1375}
1376
1377define i1 @test_sign_pos(float %x) {
1378; CHECK-LABEL: @test_sign_pos(
1379; CHECK-NEXT:    ret i1 true
1380;
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
1385}
1386
1387define i1 @test_sign_pos_half(half %x) {
1388; CHECK-LABEL: @test_sign_pos_half(
1389; CHECK-NEXT:    ret i1 true
1390;
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
1395}
1396
1397define 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]]
1403;
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
1408}
1409
1410define i1 @test_sign_neg(float %x) {
1411; CHECK-LABEL: @test_sign_neg(
1412; CHECK-NEXT:    ret i1 true
1413;
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
1419}
1420
1421define <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
1424;
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
1429}
1430
1431define i32 @test_inf_only(float nofpclass(nan sub norm zero) %x) {
1432; CHECK-LABEL: @test_inf_only(
1433; CHECK-NEXT:    ret i32 2139095040
1434;
1435  %y = bitcast float %x to i32
1436  %and = and i32 %y, 2147483647
1437  ret i32 %and
1438}
1439
1440define 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
1443;
1444  %y = bitcast bfloat %x to i16
1445  %and = and i16 %y, 32767
1446  ret i16 %and
1447}
1448
1449define 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
1452;
1453  %y = bitcast ppc_fp128 %x to i128
1454  %and = and i128 %y, 170141183460469231731687303715884105727
1455  ret i128 %and
1456}
1457
1458define i32 @test_zero_only(float nofpclass(nan sub norm inf) %x) {
1459; CHECK-LABEL: @test_zero_only(
1460; CHECK-NEXT:    ret i32 0
1461;
1462  %y = bitcast float %x to i32
1463  %and = and i32 %y, 2147483647
1464  ret i32 %and
1465}
1466
1467define 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
1470;
1471  %y = bitcast x86_fp80 %x to i80
1472  %and = and i80 %y, 604462909807314587353087
1473  ret i80 %and
1474}
1475
1476define 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]]
1481;
1482  %y = bitcast float %x to i32
1483  %and = and i32 %y, 2130706432
1484  ret i32 %and
1485}
1486
1487define 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]]
1492;
1493  %y = bitcast float %x to i32
1494  %and = and i32 %y, 2130706432
1495  ret i32 %and
1496}
1497
1498define 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]]
1503;
1504  %y = bitcast float %x to i32
1505  %and = and i32 %y, 16777215
1506  ret i32 %and
1507}
1508
1509; Make sure that the signbit is cleared.
1510define 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
1518;
1519  %cmp = fcmp oeq double %x, 0xFFF0000000000000
1520  br i1 %cmp, label %if.then, label %if.else
1521
1522if.then:
1523  %cast = bitcast double %x to i64
1524  %trunc = trunc i64 %cast to i32
1525  ret i32 %trunc
1526
1527if.else:
1528  ret i32 0
1529}
1530
1531define i1 @test_simplify_icmp(i32 %x) {
1532; CHECK-LABEL: @test_simplify_icmp(
1533; CHECK-NEXT:    ret i1 false
1534;
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
1540}
1541
1542define 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]]
1547;
1548  %bits = bitcast float %x to i32
1549  %masked = and i32 %bits, 4194304
1550  ret i32 %masked
1551}
1552
1553define 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]]
1558;
1559  %bits = bitcast float %x to i32
1560  %masked = and i32 %bits, 2097152
1561  ret i32 %masked
1562}
1563
1564define 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]]
1569;
1570  %bits = bitcast float %x to i32
1571  %masked = and i32 %bits, 4194304
1572  ret i32 %masked
1573}
1574
1575define 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]]
1580;
1581  %bits = bitcast float %x to i32
1582  %masked = and i32 %bits, 2097152
1583  ret i32 %masked
1584}
1585
1586define 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
1595;
1596  %conv = uitofp i32 %ui to float
1597  %cmp = fcmp olt float %x, %conv
1598  br i1 %cmp, label %if.else, label %if.end
1599
1600if.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
1607
1608if.else:
1609  ret i16 0
1610}
1611
1612; TODO: %cmp always evaluates to false
1613
1614define 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
1625;
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
1629
1630if.then:
1631  %cast = bitcast double %x to i64
1632  %cmp = icmp eq i64 %cast, 3458764513820540928
1633  ret i1 %cmp
1634
1635if.else:
1636  ret i1 false
1637}
1638
1639define 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]]
1644;
1645  %y = bitcast float %x to i32
1646  %and = and i32 %y, 4194304
1647  ret i32 %and
1648}
1649
1650define 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]]
1655;
1656  %y = bitcast float %x to i32
1657  %and = and i32 %y, 4194304
1658  ret i32 %and
1659}
1660
1661; Make sure that we don't crash when the use of x is unreachable.
1662define 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
1672;
1673  %cmp = fcmp uno double %x, 0.000000e+00
1674  br i1 %cmp, label %if.then1, label %if.else
1675
1676if.then1:
1677  br i1 %cmp, label %if.else, label %if.then2
1678
1679if.then2:
1680  %cast = bitcast double %x to i64
1681  %and = and i64 %cast, 1
1682  ret i64 %and
1683
1684if.else:
1685  ret i64 0
1686}
1687
1688define 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]]
1693;
1694  %y = bitcast float %x to i32
1695  %and = and i32 %y, 4194304
1696  ret i32 %and
1697}
1698
1699; We cannot make assumptions about the sign of result of sqrt
1700; when the input is a negative value (except for -0).
1701define 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]]
1707;
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
1712}
1713
1714define 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]]
1720;
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
1725}
1726
1727define 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
1730;
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
1735}
1736
1737define 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:%.*]]
1747;
1748entry:
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
1752
1753if.then:
1754  %r = and i8 %n, 32
1755  ret i8 %r
1756
1757if.else:
1758  ret i8 %other
1759}
1760
1761define 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:%.*]]
1772;
1773entry:
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
1777
1778if.then:
1779  %r = and i8 %n, 32
1780  ret i8 %r
1781
1782if.else:
1783  ret i8 %other
1784}
1785
1786define 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
1796;
1797entry:
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
1801
1802if.then:
1803  ret i8 %other
1804if.else:
1805  %r = and i8 %n, 32
1806  ret i8 %r
1807
1808}
1809
1810define 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:%.*]]
1821;
1822entry:
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
1826
1827if.then:
1828  %r = and i8 %n, 32
1829  ret i8 %r
1830
1831if.else:
1832  ret i8 %other
1833}
1834
1835define 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:%.*]]
1846;
1847entry:
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
1851
1852if.then:
1853  %r = and i8 %n, 32
1854  ret i8 %r
1855
1856if.else:
1857  ret i8 %other
1858}
1859
1860define 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:%.*]]
1870;
1871entry:
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
1875
1876if.then:
1877  %r = and i8 %n, 32
1878  ret i8 %r
1879
1880if.else:
1881  ret i8 %other
1882}
1883
1884define 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:%.*]]
1895;
1896entry:
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
1900
1901if.then:
1902  %r = and i8 %n2, 32
1903  ret i8 %r
1904
1905if.else:
1906  ret i8 %other
1907}
1908
1909define 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
1919;
1920entry:
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
1924
1925if.then:
1926  ret i8 %other
1927if.else:
1928  %r = and i8 %n, 32
1929  ret i8 %r
1930
1931}
1932
1933define 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]]
1944;
1945entry:
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
1949
1950if.then:
1951  ret i8 %other
1952if.else:
1953  %r = and i8 %n, 32
1954  ret i8 %r
1955
1956}
1957
1958
1959define 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:%.*]]
1970;
1971entry:
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
1975
1976if.then:
1977  %r = and i8 %n, 32
1978  ret i8 %r
1979
1980if.else:
1981  ret i8 %other
1982}
1983
1984define 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:%.*]]
1995;
1996entry:
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
2000
2001if.then:
2002  %r = and i8 %n, 32
2003  ret i8 %r
2004
2005if.else:
2006  ret i8 %other
2007}
2008
2009define 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
2016;
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
2024}
2025
2026define 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]]
2036;
2037entry:
2038  %v = load i64, ptr %p1, align 8
2039  %conv = trunc i64 %v to i16
2040  br i1 %c, label %exit, label %if
2041
2042if:
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
2049
2050exit:
2051  ret i16 %conv
2052}
2053
2054define i1 @mul_nuw_nsw_nonneg_const(i8 %x) {
2055; CHECK-LABEL: @mul_nuw_nsw_nonneg_const(
2056; CHECK-NEXT:    ret i1 true
2057;
2058  %mul = mul nuw nsw i8 %x, 3
2059  %cmp = icmp sgt i8 %mul, -1
2060  ret i1 %cmp
2061}
2062
2063define 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]]
2067;
2068  %mul = mul nsw i8 %x, 3
2069  %cmp = icmp sgt i8 %mul, -1
2070  ret i1 %cmp
2071}
2072
2073define 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]]
2078;
2079  %mul = mul nuw i8 %x, 3
2080  %cmp = icmp sgt i8 %mul, -1
2081  ret i1 %cmp
2082}
2083
2084define 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]]
2090;
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
2095}
2096
2097define 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
2100;
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
2106}
2107
2108define 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
2111;
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
2117}
2118
2119declare void @dummy()
2120declare void @use(i1)
2121declare void @sink(i8)
2122