xref: /llvm-project/llvm/test/Transforms/InstCombine/icmp-range.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3; These should be InstSimplify checks, but most of the code
4; is currently only in InstCombine.  TODO: move supporting code
5
6declare void @use(i8)
7declare void @use_vec(<2 x i8>)
8
9; Definitely out of range
10define i1 @test_nonzero(ptr nocapture readonly %arg) {
11; CHECK-LABEL: @test_nonzero(
12; CHECK-NEXT:    ret i1 true
13;
14  %val = load i32, ptr %arg, !range !0
15  %rval = icmp ne i32 %val, 0
16  ret i1 %rval
17}
18define i1 @test_nonzero2(ptr nocapture readonly %arg) {
19; CHECK-LABEL: @test_nonzero2(
20; CHECK-NEXT:    ret i1 false
21;
22  %val = load i32, ptr %arg, !range !0
23  %rval = icmp eq i32 %val, 0
24  ret i1 %rval
25}
26
27; Potentially in range
28define i1 @test_nonzero3(ptr nocapture readonly %arg) {
29; CHECK-LABEL: @test_nonzero3(
30; CHECK-NEXT:    [[VAL:%.*]] = load i32, ptr [[ARG:%.*]], align 4, !range [[RNG0:![0-9]+]]
31; CHECK-NEXT:    [[RVAL:%.*]] = icmp ne i32 [[VAL]], 0
32; CHECK-NEXT:    ret i1 [[RVAL]]
33;
34; Check that this does not trigger - it wouldn't be legal
35  %val = load i32, ptr %arg, !range !1
36  %rval = icmp ne i32 %val, 0
37  ret i1 %rval
38}
39
40; Definitely in range
41define i1 @test_nonzero4(ptr nocapture readonly %arg) {
42; CHECK-LABEL: @test_nonzero4(
43; CHECK-NEXT:    ret i1 false
44;
45  %val = load i8, ptr %arg, !range !2
46  %rval = icmp ne i8 %val, 0
47  ret i1 %rval
48}
49
50define i1 @test_nonzero5(ptr nocapture readonly %arg) {
51; CHECK-LABEL: @test_nonzero5(
52; CHECK-NEXT:    ret i1 false
53;
54  %val = load i8, ptr %arg, !range !2
55  %rval = icmp ugt i8 %val, 0
56  ret i1 %rval
57}
58
59; Cheaper checks (most values in range meet requirements)
60define i1 @test_nonzero6(ptr %argw) {
61; CHECK-LABEL: @test_nonzero6(
62; CHECK-NEXT:    [[VAL:%.*]] = load i8, ptr [[ARGW:%.*]], align 1, !range [[RNG1:![0-9]+]]
63; CHECK-NEXT:    [[RVAL:%.*]] = icmp ne i8 [[VAL]], 0
64; CHECK-NEXT:    ret i1 [[RVAL]]
65;
66  %val = load i8, ptr %argw, !range !3
67  %rval = icmp sgt i8 %val, 0
68  ret i1 %rval
69}
70
71; Constant not in range, should return true.
72define i1 @test_not_in_range(ptr nocapture readonly %arg) {
73; CHECK-LABEL: @test_not_in_range(
74; CHECK-NEXT:    ret i1 true
75;
76  %val = load i32, ptr %arg, !range !0
77  %rval = icmp ne i32 %val, 6
78  ret i1 %rval
79}
80
81; Constant in range, can not fold.
82define i1 @test_in_range(ptr nocapture readonly %arg) {
83; CHECK-LABEL: @test_in_range(
84; CHECK-NEXT:    [[VAL:%.*]] = load i32, ptr [[ARG:%.*]], align 4, !range [[RNG2:![0-9]+]]
85; CHECK-NEXT:    [[RVAL:%.*]] = icmp ne i32 [[VAL]], 3
86; CHECK-NEXT:    ret i1 [[RVAL]]
87;
88  %val = load i32, ptr %arg, !range !0
89  %rval = icmp ne i32 %val, 3
90  ret i1 %rval
91}
92
93; Values in range greater than constant.
94define i1 @test_range_sgt_constant(ptr nocapture readonly %arg) {
95; CHECK-LABEL: @test_range_sgt_constant(
96; CHECK-NEXT:    ret i1 true
97;
98  %val = load i32, ptr %arg, !range !0
99  %rval = icmp sgt i32 %val, 0
100  ret i1 %rval
101}
102
103; Values in range less than constant.
104define i1 @test_range_slt_constant(ptr nocapture readonly %arg) {
105; CHECK-LABEL: @test_range_slt_constant(
106; CHECK-NEXT:    ret i1 false
107;
108  %val = load i32, ptr %arg, !range !0
109  %rval = icmp sgt i32 %val, 6
110  ret i1 %rval
111}
112
113; Values in union of multiple sub ranges not equal to constant.
114define i1 @test_multi_range1(ptr nocapture readonly %arg) {
115; CHECK-LABEL: @test_multi_range1(
116; CHECK-NEXT:    ret i1 true
117;
118  %val = load i32, ptr %arg, !range !4
119  %rval = icmp ne i32 %val, 0
120  ret i1 %rval
121}
122
123; Values in multiple sub ranges not equal to constant, but in
124; union of sub ranges could possibly equal to constant. This
125; in theory could also be folded and might be implemented in
126; the future if shown profitable in practice.
127define i1 @test_multi_range2(ptr nocapture readonly %arg) {
128; CHECK-LABEL: @test_multi_range2(
129; CHECK-NEXT:    [[VAL:%.*]] = load i32, ptr [[ARG:%.*]], align 4, !range [[RNG3:![0-9]+]]
130; CHECK-NEXT:    [[RVAL:%.*]] = icmp ne i32 [[VAL]], 7
131; CHECK-NEXT:    ret i1 [[RVAL]]
132;
133  %val = load i32, ptr %arg, !range !4
134  %rval = icmp ne i32 %val, 7
135  ret i1 %rval
136}
137
138; Values' ranges overlap each other, so it can not be simplified.
139define i1 @test_two_ranges(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) {
140; CHECK-LABEL: @test_two_ranges(
141; CHECK-NEXT:    [[VAL1:%.*]] = load i32, ptr [[ARG1:%.*]], align 4, !range [[RNG4:![0-9]+]]
142; CHECK-NEXT:    [[VAL2:%.*]] = load i32, ptr [[ARG2:%.*]], align 4, !range [[RNG5:![0-9]+]]
143; CHECK-NEXT:    [[RVAL:%.*]] = icmp samesign ult i32 [[VAL2]], [[VAL1]]
144; CHECK-NEXT:    ret i1 [[RVAL]]
145;
146  %val1 = load i32, ptr %arg1, !range !5
147  %val2 = load i32, ptr %arg2, !range !6
148  %rval = icmp ult i32 %val2, %val1
149  ret i1 %rval
150}
151
152; Values' ranges overlap each other, so it can not be simplified.
153define i1 @test_two_attribute_ranges(i32 range(i32 5, 10) %arg1, i32 range(i32 8, 16) %arg2) {
154; CHECK-LABEL: @test_two_attribute_ranges(
155; CHECK-NEXT:    [[RVAL:%.*]] = icmp samesign ult i32 [[ARG2:%.*]], [[ARG1:%.*]]
156; CHECK-NEXT:    ret i1 [[RVAL]]
157;
158  %rval = icmp ult i32 %arg2, %arg1
159  ret i1 %rval
160}
161
162; Values' ranges do not overlap each other, so it can simplified to false.
163define i1 @test_two_ranges2(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) {
164; CHECK-LABEL: @test_two_ranges2(
165; CHECK-NEXT:    ret i1 false
166;
167  %val1 = load i32, ptr %arg1, !range !0
168  %val2 = load i32, ptr %arg2, !range !6
169  %rval = icmp ult i32 %val2, %val1
170  ret i1 %rval
171}
172
173; Values' ranges do not overlap each other, so it can simplified to false.
174define i1 @test_two_argument_ranges(i32 range(i32 1, 6) %arg1, i32 range(i32 8, 16) %arg2) {
175; CHECK-LABEL: @test_two_argument_ranges(
176; CHECK-NEXT:    ret i1 false
177;
178  %rval = icmp ult i32 %arg2, %arg1
179  ret i1 %rval
180}
181
182; Values' ranges do not overlap each other, so it can simplified to false.
183define i1 @test_one_range_and_one_argument_range(ptr nocapture readonly %arg1, i32 range(i32 8, 16) %arg2) {
184; CHECK-LABEL: @test_one_range_and_one_argument_range(
185; CHECK-NEXT:    ret i1 false
186;
187  %val1 = load i32, ptr %arg1, !range !0
188  %rval = icmp ult i32 %arg2, %val1
189  ret i1 %rval
190}
191
192; Values' ranges do not overlap each other, so it can simplified to false.
193define i1 @test_one_argument_range_and_one_range(i32 range(i32 1, 6) %arg1, ptr nocapture readonly %arg2) {
194; CHECK-LABEL: @test_one_argument_range_and_one_range(
195; CHECK-NEXT:    ret i1 false
196;
197  %val1 = load i32, ptr %arg2, !range !6
198  %rval = icmp ult i32 %val1, %arg1
199  ret i1 %rval
200}
201
202; Values' ranges do not overlap each other, so it can simplified to true.
203define i1 @test_two_ranges3(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) {
204; CHECK-LABEL: @test_two_ranges3(
205; CHECK-NEXT:    ret i1 true
206;
207  %val1 = load i32, ptr %arg1, !range !0
208  %val2 = load i32, ptr %arg2, !range !6
209  %rval = icmp ugt i32 %val2, %val1
210  ret i1 %rval
211}
212
213; Values' ranges overlap each other, so it can not be simplified.
214define <2 x i1> @test_two_ranges_vec(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) {
215; CHECK-LABEL: @test_two_ranges_vec(
216; CHECK-NEXT:    [[VAL1:%.*]] = load <2 x i32>, ptr [[ARG1:%.*]], align 8, !range [[RNG4]]
217; CHECK-NEXT:    [[VAL2:%.*]] = load <2 x i32>, ptr [[ARG2:%.*]], align 8, !range [[RNG5]]
218; CHECK-NEXT:    [[RVAL:%.*]] = icmp samesign ult <2 x i32> [[VAL2]], [[VAL1]]
219; CHECK-NEXT:    ret <2 x i1> [[RVAL]]
220;
221  %val1 = load <2 x i32>, ptr %arg1, !range !5
222  %val2 = load <2 x i32>, ptr %arg2, !range !6
223  %rval = icmp ult <2 x i32> %val2, %val1
224  ret <2 x i1> %rval
225}
226
227; Values' ranges do not overlap each other, so it can simplified to false.
228define <2 x i1> @test_two_ranges_vec_false(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) {
229; CHECK-LABEL: @test_two_ranges_vec_false(
230; CHECK-NEXT:    ret <2 x i1> zeroinitializer
231;
232  %val1 = load <2 x i32>, ptr %arg1, !range !0
233  %val2 = load <2 x i32>, ptr %arg2, !range !6
234  %rval = icmp ult <2 x i32> %val2, %val1
235  ret <2 x i1> %rval
236}
237
238; Values' ranges do not overlap each other, so it can simplified to true.
239define <2 x i1> @test_two_ranges_vec_true(ptr nocapture readonly %arg1, ptr nocapture readonly %arg2) {
240; CHECK-LABEL: @test_two_ranges_vec_true(
241; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
242;
243  %val1 = load <2 x i32>, ptr %arg1, !range !0
244  %val2 = load <2 x i32>, ptr %arg2, !range !6
245  %rval = icmp ugt <2 x i32> %val2, %val1
246  ret <2 x i1> %rval
247}
248
249; Values' ranges overlap each other, so it can not be simplified.
250define <2 x i1> @test_two_argument_ranges_vec(<2 x i32> range(i32 5, 10) %arg1, <2 x i32> range(i32 8, 16) %arg2) {
251; CHECK-LABEL: @test_two_argument_ranges_vec(
252; CHECK-NEXT:    [[RVAL:%.*]] = icmp samesign ult <2 x i32> [[ARG2:%.*]], [[ARG1:%.*]]
253; CHECK-NEXT:    ret <2 x i1> [[RVAL]]
254;
255  %rval = icmp ult <2 x i32> %arg2, %arg1
256  ret <2 x i1> %rval
257}
258
259; Values' ranges do not overlap each other, so it can simplified to false.
260define <2 x i1> @test_two_argument_ranges_vec_false(<2 x i32> range(i32 1, 6) %arg1, <2 x i32> range(i32 8, 16) %arg2) {
261; CHECK-LABEL: @test_two_argument_ranges_vec_false(
262; CHECK-NEXT:    ret <2 x i1> zeroinitializer
263;
264  %rval = icmp ult <2 x i32> %arg2, %arg1
265  ret <2 x i1> %rval
266}
267
268; Values' ranges do not overlap each other, so it can simplified to true.
269define <2 x i1> @test_two_argument_ranges_vec_true(<2 x i32> range(i32 1, 6) %arg1, <2 x i32> range(i32 8, 16) %arg2) {
270; CHECK-LABEL: @test_two_argument_ranges_vec_true(
271; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
272;
273  %rval = icmp ugt <2 x i32> %arg2, %arg1
274  ret <2 x i1> %rval
275}
276
277declare i32 @create_range1()
278declare range(i32 8, 16) i32 @create_range2()
279declare range(i32 1, 6) i32 @create_range3()
280
281; Values' ranges overlap each other, so it can not be simplified.
282define i1 @test_two_return_attribute_ranges_not_simplified() {
283; CHECK-LABEL: @test_two_return_attribute_ranges_not_simplified(
284; CHECK-NEXT:    [[VAL1:%.*]] = call range(i32 5, 10) i32 @create_range1()
285; CHECK-NEXT:    [[VAL2:%.*]] = call i32 @create_range2()
286; CHECK-NEXT:    [[RVAL:%.*]] = icmp samesign ult i32 [[VAL2]], [[VAL1]]
287; CHECK-NEXT:    ret i1 [[RVAL]]
288;
289  %val1 = call range(i32 5, 10) i32 @create_range1()
290  %val2 = call i32 @create_range2()
291  %rval = icmp ult i32 %val2, %val1
292  ret i1 %rval
293}
294
295; Values' ranges do not overlap each other, so it can simplified to false.
296define i1 @test_two_return_attribute_ranges_one_in_call() {
297; CHECK-LABEL: @test_two_return_attribute_ranges_one_in_call(
298; CHECK-NEXT:    [[VAL1:%.*]] = call range(i32 1, 6) i32 @create_range1()
299; CHECK-NEXT:    [[VAL2:%.*]] = call i32 @create_range2()
300; CHECK-NEXT:    ret i1 false
301;
302  %val1 = call range(i32 1, 6) i32 @create_range1()
303  %val2 = call i32 @create_range2()
304  %rval = icmp ult i32 %val2, %val1
305  ret i1 %rval
306}
307
308; Values' ranges do not overlap each other, so it can simplified to false.
309define i1 @test_two_return_attribute_ranges() {
310; CHECK-LABEL: @test_two_return_attribute_ranges(
311; CHECK-NEXT:    [[VAL1:%.*]] = call i32 @create_range3()
312; CHECK-NEXT:    [[VAL2:%.*]] = call i32 @create_range2()
313; CHECK-NEXT:    ret i1 false
314;
315  %val1 = call i32 @create_range3()
316  %val2 = call i32 @create_range2()
317  %rval = icmp ult i32 %val2, %val1
318  ret i1 %rval
319}
320
321; Values' ranges do not overlap each other, so it can simplified to false.
322define i1 @test_one_return_argument_and_one_argument_range(i32 range(i32 8, 16) %arg1) {
323; CHECK-LABEL: @test_one_return_argument_and_one_argument_range(
324; CHECK-NEXT:    [[VAL1:%.*]] = call i32 @create_range3()
325; CHECK-NEXT:    ret i1 false
326;
327  %val1 = call i32 @create_range3()
328  %rval = icmp ult i32 %arg1, %val1
329  ret i1 %rval
330}
331
332; Values' ranges do not overlap each other, so it can simplified to false.
333define i1 @test_one_range_and_one_return_argument(ptr nocapture readonly %arg1) {
334; CHECK-LABEL: @test_one_range_and_one_return_argument(
335; CHECK-NEXT:    [[VAL1:%.*]] = call i32 @create_range3()
336; CHECK-NEXT:    ret i1 false
337;
338  %val1 = call i32 @create_range3()
339  %val2 = load i32, ptr %arg1, !range !6
340  %rval = icmp ult i32 %val2, %val1
341  ret i1 %rval
342}
343
344define i1 @ugt_zext(i1 %b, i8 %x) {
345; CHECK-LABEL: @ugt_zext(
346; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], 0
347; CHECK-NEXT:    [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]]
348; CHECK-NEXT:    ret i1 [[R]]
349;
350  %z = zext i1 %b to i8
351  %r = icmp ugt i8 %z, %x
352  ret i1 %r
353}
354
355define <2 x i1> @ult_zext(<2 x i1> %b, <2 x i8> %p) {
356; CHECK-LABEL: @ult_zext(
357; CHECK-NEXT:    [[X:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]
358; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X]], zeroinitializer
359; CHECK-NEXT:    [[R:%.*]] = and <2 x i1> [[TMP1]], [[B:%.*]]
360; CHECK-NEXT:    ret <2 x i1> [[R]]
361;
362  %x = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
363  %z = zext <2 x i1> %b to <2 x i8>
364  %r = icmp ult <2 x i8> %x, %z
365  ret <2 x i1> %r
366}
367
368; negative test - need ult/ugt
369
370define i1 @uge_zext(i1 %b, i8 %x) {
371; CHECK-LABEL: @uge_zext(
372; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[B:%.*]] to i8
373; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[X:%.*]], [[Z]]
374; CHECK-NEXT:    ret i1 [[R]]
375;
376  %z = zext i1 %b to i8
377  %r = icmp uge i8 %z, %x
378  ret i1 %r
379}
380
381; negative test - need ult/ugt
382
383define i1 @ule_zext(i1 %b, i8 %p) {
384; CHECK-LABEL: @ule_zext(
385; CHECK-NEXT:    [[X:%.*]] = mul i8 [[P:%.*]], [[P]]
386; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[B:%.*]] to i8
387; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[X]], [[Z]]
388; CHECK-NEXT:    ret i1 [[R]]
389;
390  %x = mul i8 %p, %p ; thwart complexity-based canonicalization
391  %z = zext i1 %b to i8
392  %r = icmp ule i8 %x, %z
393  ret i1 %r
394}
395
396; negative test - extra use
397
398define i1 @ugt_zext_use(i1 %b, i8 %x) {
399; CHECK-LABEL: @ugt_zext_use(
400; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[B:%.*]] to i8
401; CHECK-NEXT:    call void @use(i8 [[Z]])
402; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[X:%.*]], [[Z]]
403; CHECK-NEXT:    ret i1 [[R]]
404;
405  %z = zext i1 %b to i8
406  call void @use(i8 %z)
407  %r = icmp ugt i8 %z, %x
408  ret i1 %r
409}
410
411; negative test - must be zext of i1
412
413define i1 @ult_zext_not_i1(i2 %b, i8 %x) {
414; CHECK-LABEL: @ult_zext_not_i1(
415; CHECK-NEXT:    [[Z:%.*]] = zext i2 [[B:%.*]] to i8
416; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[X:%.*]], [[Z]]
417; CHECK-NEXT:    ret i1 [[R]]
418;
419  %z = zext i2 %b to i8
420  %r = icmp ult i8 %x, %z
421  ret i1 %r
422}
423
424; sub is eliminated
425
426define i1 @sub_ult_zext(i1 %b, i8 %x, i8 %y) {
427; CHECK-LABEL: @sub_ult_zext(
428; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
429; CHECK-NEXT:    [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]]
430; CHECK-NEXT:    ret i1 [[R]]
431;
432  %z = zext i1 %b to i8
433  %s = sub i8 %x, %y
434  %r = icmp ult i8 %s, %z
435  ret i1 %r
436}
437
438define i1 @zext_ult_zext(i1 %b, i8 %p) {
439; CHECK-LABEL: @zext_ult_zext(
440; CHECK-NEXT:    [[X:%.*]] = mul i8 [[P:%.*]], [[P]]
441; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X]], 0
442; CHECK-NEXT:    [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]]
443; CHECK-NEXT:    ret i1 [[R]]
444;
445  %x = mul i8 %p, %p ; thwart complexity-based canonicalization
446  %z = zext i1 %b to i16
447  %zx = zext i8 %x to i16
448  %r = icmp ult i16 %zx, %z
449  ret i1 %r
450}
451
452; match and fold even if both sides are zexts (from different source types)
453
454define i1 @zext_ugt_zext(i1 %b, i4 %x) {
455; CHECK-LABEL: @zext_ugt_zext(
456; CHECK-NEXT:    [[ZX:%.*]] = zext i4 [[X:%.*]] to i8
457; CHECK-NEXT:    call void @use(i8 [[ZX]])
458; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i4 [[X]], 0
459; CHECK-NEXT:    [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]]
460; CHECK-NEXT:    ret i1 [[R]]
461;
462  %z = zext i1 %b to i8
463  %zx = zext i4 %x to i8
464  call void @use(i8 %zx)
465  %r = icmp ugt i8 %z, %zx
466  ret i1 %r
467}
468
469; negative test - must be zext of i1
470
471define i1 @sub_ult_zext_not_i1(i2 %b, i8 %x, i8 %y) {
472; CHECK-LABEL: @sub_ult_zext_not_i1(
473; CHECK-NEXT:    [[Z:%.*]] = zext i2 [[B:%.*]] to i8
474; CHECK-NEXT:    [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
475; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[S]], [[Z]]
476; CHECK-NEXT:    ret i1 [[R]]
477;
478  %z = zext i2 %b to i8
479  %s = sub i8 %x, %y
480  %r = icmp ult i8 %s, %z
481  ret i1 %r
482}
483
484; negative test - extra use (but we could try harder to fold this)
485
486define i1 @sub_ult_zext_use1(i1 %b, i8 %x, i8 %y) {
487; CHECK-LABEL: @sub_ult_zext_use1(
488; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[B:%.*]] to i8
489; CHECK-NEXT:    call void @use(i8 [[Z]])
490; CHECK-NEXT:    [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
491; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[S]], [[Z]]
492; CHECK-NEXT:    ret i1 [[R]]
493;
494  %z = zext i1 %b to i8
495  call void @use(i8 %z)
496  %s = sub i8 %x, %y
497  %r = icmp ult i8 %s, %z
498  ret i1 %r
499}
500
501define <2 x i1> @zext_ugt_sub_use2(<2 x i1> %b, <2 x i8> %x, <2 x i8> %y) {
502; CHECK-LABEL: @zext_ugt_sub_use2(
503; CHECK-NEXT:    [[S:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]]
504; CHECK-NEXT:    call void @use_vec(<2 x i8> [[S]])
505; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X]], [[Y]]
506; CHECK-NEXT:    [[R:%.*]] = and <2 x i1> [[TMP1]], [[B:%.*]]
507; CHECK-NEXT:    ret <2 x i1> [[R]]
508;
509  %z = zext <2 x i1> %b to <2 x i8>
510  %s = sub <2 x i8> %x, %y
511  call void @use_vec(<2 x i8> %s)
512  %r = icmp ugt <2 x i8> %z, %s
513  ret <2 x i1> %r
514}
515
516define i1 @sub_ult_zext_use3(i1 %b, i8 %x, i8 %y) {
517; CHECK-LABEL: @sub_ult_zext_use3(
518; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[B:%.*]] to i8
519; CHECK-NEXT:    call void @use(i8 [[Z]])
520; CHECK-NEXT:    [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
521; CHECK-NEXT:    call void @use(i8 [[S]])
522; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[S]], [[Z]]
523; CHECK-NEXT:    ret i1 [[R]]
524;
525  %z = zext i1 %b to i8
526  call void @use(i8 %z)
527  %s = sub i8 %x, %y
528  call void @use(i8 %s)
529  %r = icmp ult i8 %s, %z
530  ret i1 %r
531}
532
533define i1 @sub_ule_zext(i1 %b, i8 %x, i8 %y) {
534; CHECK-LABEL: @sub_ule_zext(
535; CHECK-NEXT:    [[Z:%.*]] = zext i1 [[B:%.*]] to i8
536; CHECK-NEXT:    [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
537; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[S]], [[Z]]
538; CHECK-NEXT:    ret i1 [[R]]
539;
540  %z = zext i1 %b to i8
541  %s = sub i8 %x, %y
542  %r = icmp ule i8 %s, %z
543  ret i1 %r
544}
545
546define <2 x i1> @sub_ult_and(<2 x i8> %b, <2 x i8> %x, <2 x i8> %y) {
547; CHECK-LABEL: @sub_ult_and(
548; CHECK-NEXT:    [[A:%.*]] = and <2 x i8> [[B:%.*]], splat (i8 1)
549; CHECK-NEXT:    [[S:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]]
550; CHECK-NEXT:    [[R:%.*]] = icmp ult <2 x i8> [[S]], [[A]]
551; CHECK-NEXT:    ret <2 x i1> [[R]]
552;
553  %a = and <2 x i8> %b, <i8 1, i8 1>
554  %s = sub <2 x i8> %x, %y
555  %r = icmp ult <2 x i8> %s, %a
556  ret <2 x i1> %r
557}
558
559define i1 @and_ugt_sub(i8 %b, i8 %x, i8 %y) {
560; CHECK-LABEL: @and_ugt_sub(
561; CHECK-NEXT:    [[A:%.*]] = and i8 [[B:%.*]], 1
562; CHECK-NEXT:    [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
563; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[A]], [[S]]
564; CHECK-NEXT:    ret i1 [[R]]
565;
566  %a = and i8 %b, 1
567  %s = sub i8 %x, %y
568  %r = icmp ugt i8 %a, %s
569  ret i1 %r
570}
571
572; Repeat the zext set of tests with a sext instead.
573
574define i1 @uge_sext(i1 %b, i8 %x) {
575; CHECK-LABEL: @uge_sext(
576; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], 0
577; CHECK-NEXT:    [[R:%.*]] = or i1 [[TMP1]], [[B:%.*]]
578; CHECK-NEXT:    ret i1 [[R]]
579;
580  %s = sext i1 %b to i8
581  %r = icmp uge i8 %s, %x
582  ret i1 %r
583}
584
585define <2 x i1> @ule_sext(<2 x i1> %b, <2 x i8> %p) {
586; CHECK-LABEL: @ule_sext(
587; CHECK-NEXT:    [[X:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]
588; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X]], zeroinitializer
589; CHECK-NEXT:    [[R:%.*]] = or <2 x i1> [[TMP1]], [[B:%.*]]
590; CHECK-NEXT:    ret <2 x i1> [[R]]
591;
592  %x = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
593  %s = sext <2 x i1> %b to <2 x i8>
594  %r = icmp ule <2 x i8> %x, %s
595  ret <2 x i1> %r
596}
597
598; negative test - need ule/uge
599
600define i1 @ugt_sext(i1 %b, i8 %x) {
601; CHECK-LABEL: @ugt_sext(
602; CHECK-NEXT:    [[S:%.*]] = sext i1 [[B:%.*]] to i8
603; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[X:%.*]], [[S]]
604; CHECK-NEXT:    ret i1 [[R]]
605;
606  %s = sext i1 %b to i8
607  %r = icmp ugt i8 %s, %x
608  ret i1 %r
609}
610
611; negative test - need ule/uge
612
613define i1 @ult_sext(i1 %b, i8 %p) {
614; CHECK-LABEL: @ult_sext(
615; CHECK-NEXT:    [[X:%.*]] = mul i8 [[P:%.*]], [[P]]
616; CHECK-NEXT:    [[S:%.*]] = sext i1 [[B:%.*]] to i8
617; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[X]], [[S]]
618; CHECK-NEXT:    ret i1 [[R]]
619;
620  %x = mul i8 %p, %p ; thwart complexity-based canonicalization
621  %s = sext i1 %b to i8
622  %r = icmp ult i8 %x, %s
623  ret i1 %r
624}
625
626; negative test - extra use
627
628define i1 @uge_sext_use(i1 %b, i8 %x) {
629; CHECK-LABEL: @uge_sext_use(
630; CHECK-NEXT:    [[S:%.*]] = sext i1 [[B:%.*]] to i8
631; CHECK-NEXT:    call void @use(i8 [[S]])
632; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[X:%.*]], [[S]]
633; CHECK-NEXT:    ret i1 [[R]]
634;
635  %s = sext i1 %b to i8
636  call void @use(i8 %s)
637  %r = icmp uge i8 %s, %x
638  ret i1 %r
639}
640
641; negative test - must be sext of i1
642
643define i1 @ule_sext_not_i1(i2 %b, i8 %x) {
644; CHECK-LABEL: @ule_sext_not_i1(
645; CHECK-NEXT:    [[S:%.*]] = sext i2 [[B:%.*]] to i8
646; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[X:%.*]], [[S]]
647; CHECK-NEXT:    ret i1 [[R]]
648;
649  %s = sext i2 %b to i8
650  %r = icmp ule i8 %x, %s
651  ret i1 %r
652}
653
654; sub is eliminated
655
656define i1 @sub_ule_sext(i1 %b, i8 %x, i8 %y) {
657; CHECK-LABEL: @sub_ule_sext(
658; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], [[Y:%.*]]
659; CHECK-NEXT:    [[R:%.*]] = or i1 [[TMP1]], [[B:%.*]]
660; CHECK-NEXT:    ret i1 [[R]]
661;
662  %s = sext i1 %b to i8
663  %d = sub i8 %x, %y
664  %r = icmp ule i8 %d, %s
665  ret i1 %r
666}
667
668define i1 @sext_ule_sext(i1 %b, i8 %p) {
669; CHECK-LABEL: @sext_ule_sext(
670; CHECK-NEXT:    [[X:%.*]] = mul i8 [[P:%.*]], [[P]]
671; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X]], 0
672; CHECK-NEXT:    [[R:%.*]] = or i1 [[TMP1]], [[B:%.*]]
673; CHECK-NEXT:    ret i1 [[R]]
674;
675  %x = mul i8 %p, %p ; thwart complexity-based canonicalization
676  %s = sext i1 %b to i16
677  %sx = sext i8 %x to i16
678  %r = icmp ule i16 %sx, %s
679  ret i1 %r
680}
681
682; match and fold even if both sides are sexts (from different source types)
683
684define i1 @sext_uge_sext(i1 %b, i4 %x) {
685; CHECK-LABEL: @sext_uge_sext(
686; CHECK-NEXT:    [[SX:%.*]] = sext i4 [[X:%.*]] to i8
687; CHECK-NEXT:    call void @use(i8 [[SX]])
688; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i4 [[X]], 0
689; CHECK-NEXT:    [[R:%.*]] = or i1 [[TMP1]], [[B:%.*]]
690; CHECK-NEXT:    ret i1 [[R]]
691;
692  %s = sext i1 %b to i8
693  %sx = sext i4 %x to i8
694  call void @use(i8 %sx)
695  %r = icmp uge i8 %s, %sx
696  ret i1 %r
697}
698
699; negative test - must be sext of i1
700
701define i1 @sub_ule_sext_not_i1(i2 %b, i8 %x, i8 %y) {
702; CHECK-LABEL: @sub_ule_sext_not_i1(
703; CHECK-NEXT:    [[S:%.*]] = sext i2 [[B:%.*]] to i8
704; CHECK-NEXT:    [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
705; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[D]], [[S]]
706; CHECK-NEXT:    ret i1 [[R]]
707;
708  %s = sext i2 %b to i8
709  %d = sub i8 %x, %y
710  %r = icmp ule i8 %d, %s
711  ret i1 %r
712}
713
714; negative test - extra use (but we could try harder to fold this)
715
716define i1 @sub_ule_sext_use1(i1 %b, i8 %x, i8 %y) {
717; CHECK-LABEL: @sub_ule_sext_use1(
718; CHECK-NEXT:    [[S:%.*]] = sext i1 [[B:%.*]] to i8
719; CHECK-NEXT:    call void @use(i8 [[S]])
720; CHECK-NEXT:    [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
721; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[D]], [[S]]
722; CHECK-NEXT:    ret i1 [[R]]
723;
724  %s = sext i1 %b to i8
725  call void @use(i8 %s)
726  %d = sub i8 %x, %y
727  %r = icmp ule i8 %d, %s
728  ret i1 %r
729}
730
731define <2 x i1> @sext_uge_sub_use2(<2 x i1> %b, <2 x i8> %x, <2 x i8> %y) {
732; CHECK-LABEL: @sext_uge_sub_use2(
733; CHECK-NEXT:    [[D:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]]
734; CHECK-NEXT:    call void @use_vec(<2 x i8> [[D]])
735; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X]], [[Y]]
736; CHECK-NEXT:    [[R:%.*]] = or <2 x i1> [[TMP1]], [[B:%.*]]
737; CHECK-NEXT:    ret <2 x i1> [[R]]
738;
739  %s = sext <2 x i1> %b to <2 x i8>
740  %d = sub <2 x i8> %x, %y
741  call void @use_vec(<2 x i8> %d)
742  %r = icmp uge <2 x i8> %s, %d
743  ret <2 x i1> %r
744}
745
746define i1 @sub_ule_sext_use3(i1 %b, i8 %x, i8 %y) {
747; CHECK-LABEL: @sub_ule_sext_use3(
748; CHECK-NEXT:    [[S:%.*]] = sext i1 [[B:%.*]] to i8
749; CHECK-NEXT:    call void @use(i8 [[S]])
750; CHECK-NEXT:    [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
751; CHECK-NEXT:    call void @use(i8 [[D]])
752; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[D]], [[S]]
753; CHECK-NEXT:    ret i1 [[R]]
754;
755  %s = sext i1 %b to i8
756  call void @use(i8 %s)
757  %d = sub i8 %x, %y
758  call void @use(i8 %d)
759  %r = icmp ule i8 %d, %s
760  ret i1 %r
761}
762
763define i1 @sub_ult_sext(i1 %b, i8 %x, i8 %y) {
764; CHECK-LABEL: @sub_ult_sext(
765; CHECK-NEXT:    [[S:%.*]] = sext i1 [[B:%.*]] to i8
766; CHECK-NEXT:    [[D:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
767; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[D]], [[S]]
768; CHECK-NEXT:    ret i1 [[R]]
769;
770  %s = sext i1 %b to i8
771  %d = sub i8 %x, %y
772  %r = icmp ult i8 %d, %s
773  ret i1 %r
774}
775
776define <2 x i1> @sub_ule_ashr(<2 x i8> %b, <2 x i8> %x, <2 x i8> %y) {
777; CHECK-LABEL: @sub_ule_ashr(
778; CHECK-NEXT:    [[A:%.*]] = ashr <2 x i8> [[B:%.*]], splat (i8 7)
779; CHECK-NEXT:    [[S:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]]
780; CHECK-NEXT:    [[R:%.*]] = icmp ule <2 x i8> [[S]], [[A]]
781; CHECK-NEXT:    ret <2 x i1> [[R]]
782;
783  %a = ashr <2 x i8> %b, <i8 7, i8 7>
784  %s = sub <2 x i8> %x, %y
785  %r = icmp ule <2 x i8> %s, %a
786  ret <2 x i1> %r
787}
788
789define i1 @ashr_uge_sub(i8 %b, i8 %x, i8 %y) {
790; CHECK-LABEL: @ashr_uge_sub(
791; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[B:%.*]], 7
792; CHECK-NEXT:    [[S:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
793; CHECK-NEXT:    [[R:%.*]] = icmp uge i8 [[A]], [[S]]
794; CHECK-NEXT:    ret i1 [[R]]
795;
796  %a = ashr i8 %b, 7
797  %s = sub i8 %x, %y
798  %r = icmp uge i8 %a, %s
799  ret i1 %r
800}
801
802; (zext i1 a) + (sext i1 b)) s< -1 --> false
803
804define i1 @zext_sext_add_icmp_slt_minus1(i1 %a, i1 %b) {
805; CHECK-LABEL: @zext_sext_add_icmp_slt_minus1(
806; CHECK-NEXT:    ret i1 false
807;
808  %zext.a = zext i1 %a to i8
809  %sext.b = sext i1 %b to i8
810  %add = add i8 %zext.a, %sext.b
811  %r = icmp slt i8 %add, -1
812  ret i1 %r
813}
814
815; (zext i1 a) + (sext i1 b)) s> 1 --> false
816
817define i1 @zext_sext_add_icmp_sgt_1(i1 %a, i1 %b) {
818; CHECK-LABEL: @zext_sext_add_icmp_sgt_1(
819; CHECK-NEXT:    ret i1 false
820;
821  %zext.a = zext i1 %a to i8
822  %sext.b = sext i1 %b to i8
823  %add = add i8 %zext.a, %sext.b
824  %r = icmp sgt i8 %add, 1
825  ret i1 %r
826}
827
828; (zext i1 a) + (sext i1 b)) s> -2 --> true
829
830define i1 @zext_sext_add_icmp_sgt_minus2(i1 %a, i1 %b) {
831; CHECK-LABEL: @zext_sext_add_icmp_sgt_minus2(
832; CHECK-NEXT:    ret i1 true
833;
834  %zext.a = zext i1 %a to i8
835  %sext.b = sext i1 %b to i8
836  %add = add i8 %zext.a, %sext.b
837  %r = icmp sgt i8 %add, -2
838  ret i1 %r
839}
840
841; (zext i1 a) + (sext i1 b)) s< 2 --> true
842
843define i1 @zext_sext_add_icmp_slt_2(i1 %a, i1 %b) {
844; CHECK-LABEL: @zext_sext_add_icmp_slt_2(
845; CHECK-NEXT:    ret i1 true
846;
847  %zext.a = zext i1 %a to i8
848  %sext.b = sext i1 %b to i8
849  %add = add i8 %zext.a, %sext.b
850  %r = icmp slt i8 %add, 2
851  ret i1 %r
852}
853
854; test case with i128
855
856define i1 @zext_sext_add_icmp_i128(i1 %a, i1 %b) {
857; CHECK-LABEL: @zext_sext_add_icmp_i128(
858; CHECK-NEXT:    ret i1 false
859;
860  %zext.a = zext i1 %a to i128
861  %sext.b = sext i1 %b to i128
862  %add = add i128 %zext.a, %sext.b
863  %r = icmp sgt i128 %add, 9223372036854775808
864  ret i1 %r
865}
866
867; (zext i1 a) + (sext i1 b)) == -1 --> ~a & b
868
869define i1 @zext_sext_add_icmp_eq_minus1(i1 %a, i1 %b) {
870; CHECK-LABEL: @zext_sext_add_icmp_eq_minus1(
871; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[A:%.*]], true
872; CHECK-NEXT:    [[R:%.*]] = and i1 [[B:%.*]], [[TMP1]]
873; CHECK-NEXT:    ret i1 [[R]]
874;
875  %zext.a = zext i1 %a to i8
876  %sext.b = sext i1 %b to i8
877  %add = add i8 %zext.a, %sext.b
878  %r = icmp eq i8 %add, -1
879  ret i1 %r
880}
881
882
883; (zext i1 a) + (sext i1 b)) != -1 --> a | ~b
884
885define i1 @zext_sext_add_icmp_ne_minus1(i1 %a, i1 %b) {
886; CHECK-LABEL: @zext_sext_add_icmp_ne_minus1(
887; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[B:%.*]], true
888; CHECK-NEXT:    [[R:%.*]] = or i1 [[A:%.*]], [[TMP1]]
889; CHECK-NEXT:    ret i1 [[R]]
890;
891  %zext.a = zext i1 %a to i8
892  %sext.b = sext i1 %b to i8
893  %add = add i8 %zext.a, %sext.b
894  %r = icmp ne i8 %add, -1
895  ret i1 %r
896}
897
898; (zext i1 a) + (sext i1 b)) s> -1 --> a | ~b
899
900define i1 @zext_sext_add_icmp_sgt_minus1(i1 %a, i1 %b) {
901; CHECK-LABEL: @zext_sext_add_icmp_sgt_minus1(
902; CHECK-NEXT:    [[B_NOT:%.*]] = xor i1 [[B:%.*]], true
903; CHECK-NEXT:    [[R:%.*]] = or i1 [[A:%.*]], [[B_NOT]]
904; CHECK-NEXT:    ret i1 [[R]]
905;
906  %zext.a = zext i1 %a to i8
907  %sext.b = sext i1 %b to i8
908  %add = add i8 %zext.a, %sext.b
909  %r = icmp sgt i8 %add, -1
910  ret i1 %r
911}
912
913; (zext i1 a) + (sext i1 b)) u< -1 --> a | ~b
914
915define i1 @zext_sext_add_icmp_ult_minus1(i1 %a, i1 %b) {
916; CHECK-LABEL: @zext_sext_add_icmp_ult_minus1(
917; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[B:%.*]], true
918; CHECK-NEXT:    [[R:%.*]] = or i1 [[A:%.*]], [[TMP1]]
919; CHECK-NEXT:    ret i1 [[R]]
920;
921  %zext.a = zext i1 %a to i8
922  %sext.b = sext i1 %b to i8
923  %add = add i8 %zext.a, %sext.b
924  %r = icmp ult i8 %add, -1
925  ret i1 %r
926}
927
928; (zext i1 a) + (sext i1 b)) s> 0 --> a & ~b
929
930define i1 @zext_sext_add_icmp_sgt_0(i1 %a, i1 %b) {
931; CHECK-LABEL: @zext_sext_add_icmp_sgt_0(
932; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[B:%.*]], true
933; CHECK-NEXT:    [[R:%.*]] = and i1 [[A:%.*]], [[TMP1]]
934; CHECK-NEXT:    ret i1 [[R]]
935;
936  %zext.a = zext i1 %a to i8
937  %sext.b = sext i1 %b to i8
938  %add = add i8 %zext.a, %sext.b
939  %r = icmp sgt i8 %add, 0
940  ret i1 %r
941}
942
943; (zext i1 a) + (sext i1 b)) s< 0 --> ~a & b
944
945define i1 @zext_sext_add_icmp_slt_0(i1 %a, i1 %b) {
946; CHECK-LABEL: @zext_sext_add_icmp_slt_0(
947; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[A:%.*]], true
948; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[B:%.*]], [[TMP1]]
949; CHECK-NEXT:    ret i1 [[TMP2]]
950;
951  %zext.a = zext i1 %a to i8
952  %sext.b = sext i1 %b to i8
953  %add = add i8 %zext.a, %sext.b
954  %r = icmp slt i8 %add, 0
955  ret i1 %r
956}
957
958; (zext i1 a) + (sext i1 b)) == 1 --> a & ~b
959
960define i1 @zext_sext_add_icmp_eq_1(i1 %a, i1 %b) {
961; CHECK-LABEL: @zext_sext_add_icmp_eq_1(
962; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[B:%.*]], true
963; CHECK-NEXT:    [[R:%.*]] = and i1 [[A:%.*]], [[TMP1]]
964; CHECK-NEXT:    ret i1 [[R]]
965;
966  %zext.a = zext i1 %a to i8
967  %sext.b = sext i1 %b to i8
968  %add = add i8 %zext.a, %sext.b
969  %r = icmp eq i8 %add, 1
970  ret i1 %r
971}
972
973; (zext i1 a) + (sext i1 b)) != 1 --> ~a | b
974
975define i1 @zext_sext_add_icmp_ne_1(i1 %a, i1 %b) {
976; CHECK-LABEL: @zext_sext_add_icmp_ne_1(
977; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[A:%.*]], true
978; CHECK-NEXT:    [[R:%.*]] = or i1 [[B:%.*]], [[TMP1]]
979; CHECK-NEXT:    ret i1 [[R]]
980;
981  %zext.a = zext i1 %a to i8
982  %sext.b = sext i1 %b to i8
983  %add = add i8 %zext.a, %sext.b
984  %r = icmp ne i8 %add, 1
985  ret i1 %r
986}
987
988; (zext i1 a) + (sext i1 b)) s< 1 --> ~a | b
989
990define i1 @zext_sext_add_icmp_slt_1(i1 %a, i1 %b) {
991; CHECK-LABEL: @zext_sext_add_icmp_slt_1(
992; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[A:%.*]], true
993; CHECK-NEXT:    [[R:%.*]] = or i1 [[B:%.*]], [[TMP1]]
994; CHECK-NEXT:    ret i1 [[R]]
995;
996  %zext.a = zext i1 %a to i8
997  %sext.b = sext i1 %b to i8
998  %add = add i8 %zext.a, %sext.b
999  %r = icmp slt i8 %add, 1
1000  ret i1 %r
1001}
1002
1003; (zext i1 a) + (sext i1 b)) u> 1 --> ~a & b
1004
1005define i1 @zext_sext_add_icmp_ugt_1(i1 %a, i1 %b) {
1006; CHECK-LABEL: @zext_sext_add_icmp_ugt_1(
1007; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[A:%.*]], true
1008; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[B:%.*]], [[TMP1]]
1009; CHECK-NEXT:    ret i1 [[TMP2]]
1010;
1011  %zext.a = zext i1 %a to i8
1012  %sext.b = sext i1 %b to i8
1013  %add = add i8 %zext.a, %sext.b
1014  %r = icmp ugt i8 %add, 1
1015  ret i1 %r
1016}
1017
1018define <2 x i1> @vector_zext_sext_add_icmp_slt_1(<2 x i1> %a, <2 x i1> %b) {
1019; CHECK-LABEL: @vector_zext_sext_add_icmp_slt_1(
1020; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i1> [[A:%.*]], splat (i1 true)
1021; CHECK-NEXT:    [[R:%.*]] = or <2 x i1> [[B:%.*]], [[TMP1]]
1022; CHECK-NEXT:    ret <2 x i1> [[R]]
1023;
1024  %zext.a = zext <2 x i1> %a to <2 x i8>
1025  %sext.b = sext <2 x i1> %b to <2 x i8>
1026  %add = add <2 x i8> %zext.a, %sext.b
1027  %r = icmp slt <2 x i8> %add, <i8 1, i8 1>
1028  ret <2 x i1> %r
1029}
1030
1031define <2 x i1> @vector_zext_sext_add_icmp_slt_1_poison(<2 x i1> %a, <2 x i1> %b) {
1032; CHECK-LABEL: @vector_zext_sext_add_icmp_slt_1_poison(
1033; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext <2 x i1> [[A:%.*]] to <2 x i8>
1034; CHECK-NEXT:    [[SEXT_B:%.*]] = sext <2 x i1> [[B:%.*]] to <2 x i8>
1035; CHECK-NEXT:    [[ADD:%.*]] = add nsw <2 x i8> [[ZEXT_A]], [[SEXT_B]]
1036; CHECK-NEXT:    [[R:%.*]] = icmp slt <2 x i8> [[ADD]], <i8 1, i8 poison>
1037; CHECK-NEXT:    ret <2 x i1> [[R]]
1038;
1039  %zext.a = zext <2 x i1> %a to <2 x i8>
1040  %sext.b = sext <2 x i1> %b to <2 x i8>
1041  %add = add <2 x i8> %zext.a, %sext.b
1042  %r = icmp slt <2 x i8> %add, <i8 1, i8 poison>
1043  ret <2 x i1> %r
1044}
1045
1046define i1 @zext_sext_add_icmp_slt_minus_1_no_oneuse(i1 %a, i1 %b) {
1047; CHECK-LABEL: @zext_sext_add_icmp_slt_minus_1_no_oneuse(
1048; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
1049; CHECK-NEXT:    [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
1050; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
1051; CHECK-NEXT:    call void @use(i8 [[ADD]])
1052; CHECK-NEXT:    ret i1 false
1053;
1054  %zext.a = zext i1 %a to i8
1055  %sext.b = sext i1 %b to i8
1056  %add = add i8 %zext.a, %sext.b
1057  call void @use(i8 %add)
1058  %r = icmp slt i8 %add, -1
1059  ret i1 %r
1060}
1061
1062define i1 @zext_sext_add_icmp_sgt_1_no_oneuse(i1 %a, i1 %b) {
1063; CHECK-LABEL: @zext_sext_add_icmp_sgt_1_no_oneuse(
1064; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
1065; CHECK-NEXT:    [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
1066; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
1067; CHECK-NEXT:    call void @use(i8 [[ADD]])
1068; CHECK-NEXT:    ret i1 false
1069;
1070  %zext.a = zext i1 %a to i8
1071  %sext.b = sext i1 %b to i8
1072  %add = add i8 %zext.a, %sext.b
1073  call void @use(i8 %add)
1074  %r = icmp sgt i8 %add, 1
1075  ret i1 %r
1076}
1077
1078define i1 @zext_sext_add_icmp_slt_2_no_oneuse(i1 %a, i1 %b) {
1079; CHECK-LABEL: @zext_sext_add_icmp_slt_2_no_oneuse(
1080; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
1081; CHECK-NEXT:    [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
1082; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
1083; CHECK-NEXT:    call void @use(i8 [[ADD]])
1084; CHECK-NEXT:    ret i1 true
1085;
1086  %zext.a = zext i1 %a to i8
1087  %sext.b = sext i1 %b to i8
1088  %add = add i8 %zext.a, %sext.b
1089  call void @use(i8 %add)
1090  %r = icmp slt i8 %add, 2
1091  ret i1 %r
1092}
1093
1094define i1 @zext_sext_add_icmp_sgt_mins_2_no_oneuse(i1 %a, i1 %b) {
1095; CHECK-LABEL: @zext_sext_add_icmp_sgt_mins_2_no_oneuse(
1096; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
1097; CHECK-NEXT:    [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
1098; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
1099; CHECK-NEXT:    call void @use(i8 [[ADD]])
1100; CHECK-NEXT:    ret i1 true
1101;
1102  %zext.a = zext i1 %a to i8
1103  %sext.b = sext i1 %b to i8
1104  %add = add i8 %zext.a, %sext.b
1105  call void @use(i8 %add)
1106  %r = icmp sgt i8 %add, -2
1107  ret i1 %r
1108}
1109
1110; Negative test, more than one use for icmp LHS
1111
1112define i1 @zext_sext_add_icmp_slt_1_no_oneuse(i1 %a, i1 %b) {
1113; CHECK-LABEL: @zext_sext_add_icmp_slt_1_no_oneuse(
1114; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
1115; CHECK-NEXT:    [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
1116; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
1117; CHECK-NEXT:    call void @use(i8 [[ADD]])
1118; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[ADD]], 1
1119; CHECK-NEXT:    ret i1 [[R]]
1120;
1121  %zext.a = zext i1 %a to i8
1122  %sext.b = sext i1 %b to i8
1123  %add = add i8 %zext.a, %sext.b
1124  call void @use(i8 %add)
1125  %r = icmp slt i8 %add, 1
1126  ret i1 %r
1127}
1128
1129; Negative test, icmp RHS is not a constant
1130
1131define i1 @zext_sext_add_icmp_slt_1_rhs_not_const(i1 %a, i1 %b, i8 %c) {
1132; CHECK-LABEL: @zext_sext_add_icmp_slt_1_rhs_not_const(
1133; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext i1 [[A:%.*]] to i8
1134; CHECK-NEXT:    [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
1135; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
1136; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[ADD]], [[C:%.*]]
1137; CHECK-NEXT:    ret i1 [[R]]
1138;
1139  %zext.a = zext i1 %a to i8
1140  %sext.b = sext i1 %b to i8
1141  %add = add i8 %zext.a, %sext.b
1142  %r = icmp slt i8 %add, %c
1143  ret i1 %r
1144}
1145
1146; Negative test, ext source is not i1
1147
1148define i1 @zext_sext_add_icmp_slt_1_type_not_i1(i2 %a, i1 %b) {
1149; CHECK-LABEL: @zext_sext_add_icmp_slt_1_type_not_i1(
1150; CHECK-NEXT:    [[ZEXT_A:%.*]] = zext i2 [[A:%.*]] to i8
1151; CHECK-NEXT:    [[SEXT_B:%.*]] = sext i1 [[B:%.*]] to i8
1152; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[ZEXT_A]], [[SEXT_B]]
1153; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[ADD]], 1
1154; CHECK-NEXT:    ret i1 [[R]]
1155;
1156  %zext.a = zext i2 %a to i8
1157  %sext.b = sext i1 %b to i8
1158  %add = add i8 %zext.a, %sext.b
1159  %r = icmp slt i8 %add, 1
1160  ret i1 %r
1161}
1162
1163define i1 @icmp_eq_bool_0(ptr %ptr) {
1164; CHECK-LABEL: @icmp_eq_bool_0(
1165; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6:![0-9]+]]
1166; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[VAL]], 0
1167; CHECK-NEXT:    ret i1 [[CMP]]
1168;
1169  %val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2}
1170  %cmp = icmp eq i64 %val, 0
1171  ret i1 %cmp
1172}
1173
1174define i1 @icmp_eq_bool_1(ptr %ptr) {
1175; CHECK-LABEL: @icmp_eq_bool_1(
1176; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6]]
1177; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[VAL]], 0
1178; CHECK-NEXT:    ret i1 [[CMP]]
1179;
1180  %val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2}
1181  %cmp = icmp eq i64 %val, 1
1182  ret i1 %cmp
1183}
1184
1185define i1 @icmp_ne_bool_0(ptr %ptr) {
1186; CHECK-LABEL: @icmp_ne_bool_0(
1187; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6]]
1188; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[VAL]], 0
1189; CHECK-NEXT:    ret i1 [[CMP]]
1190;
1191  %val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2}
1192  %cmp = icmp ne i64 %val, 0
1193  ret i1 %cmp
1194}
1195
1196define i1 @icmp_ne_bool_1(ptr %ptr) {
1197; CHECK-LABEL: @icmp_ne_bool_1(
1198; CHECK-NEXT:    [[VAL:%.*]] = load i64, ptr [[PTR:%.*]], align 8, !range [[RNG6]]
1199; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[VAL]], 0
1200; CHECK-NEXT:    ret i1 [[CMP]]
1201;
1202  %val = load i64, ptr %ptr, align 8, !range !{i64 0, i64 2}
1203  %cmp = icmp ne i64 %val, 1
1204  ret i1 %cmp
1205}
1206
1207; Tests from PR65073
1208define i1 @icmp_ne_zext_eq_zero(i32 %a) {
1209; CHECK-LABEL: @icmp_ne_zext_eq_zero(
1210; CHECK-NEXT:    ret i1 true
1211;
1212  %cmp = icmp eq i32 %a, 0
1213  %conv = zext i1 %cmp to i32
1214  %cmp1 = icmp ne i32 %conv, %a
1215  ret i1 %cmp1
1216}
1217
1218define i1 @icmp_ne_zext_ne_zero(i32 %a) {
1219; CHECK-LABEL: @icmp_ne_zext_ne_zero(
1220; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 1
1221; CHECK-NEXT:    ret i1 [[CMP1]]
1222;
1223  %cmp = icmp ne i32 %a, 0
1224  %conv = zext i1 %cmp to i32
1225  %cmp1 = icmp ne i32 %conv, %a
1226  ret i1 %cmp1
1227}
1228
1229define i1 @icmp_eq_zext_eq_zero(i32 %a) {
1230; CHECK-LABEL: @icmp_eq_zext_eq_zero(
1231; CHECK-NEXT:    ret i1 false
1232;
1233  %cmp = icmp eq i32 %a, 0
1234  %conv = zext i1 %cmp to i32
1235  %cmp1 = icmp eq i32 %conv, %a
1236  ret i1 %cmp1
1237}
1238
1239define i1 @icmp_eq_zext_ne_zero(i32 %a) {
1240; CHECK-LABEL: @icmp_eq_zext_ne_zero(
1241; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], 2
1242; CHECK-NEXT:    ret i1 [[CMP1]]
1243;
1244  %cmp = icmp ne i32 %a, 0
1245  %conv = zext i1 %cmp to i32
1246  %cmp1 = icmp eq i32 %conv, %a
1247  ret i1 %cmp1
1248}
1249
1250define i1 @icmp_ne_zext_eq_one(i32 %a) {
1251; CHECK-LABEL: @icmp_ne_zext_eq_one(
1252; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt i32 [[A:%.*]], 1
1253; CHECK-NEXT:    ret i1 [[CMP1]]
1254;
1255  %cmp = icmp eq i32 %a, 1
1256  %conv = zext i1 %cmp to i32
1257  %cmp1 = icmp ne i32 %conv, %a
1258  ret i1 %cmp1
1259}
1260
1261define i1 @icmp_ne_zext_ne_one(i32 %a) {
1262; CHECK-LABEL: @icmp_ne_zext_ne_one(
1263; CHECK-NEXT:    ret i1 true
1264;
1265  %cmp = icmp ne i32 %a, 1
1266  %conv = zext i1 %cmp to i32
1267  %cmp1 = icmp ne i32 %conv, %a
1268  ret i1 %cmp1
1269}
1270
1271define i1 @icmp_eq_zext_eq_one(i32 %a) {
1272; CHECK-LABEL: @icmp_eq_zext_eq_one(
1273; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], 2
1274; CHECK-NEXT:    ret i1 [[CMP1]]
1275;
1276  %cmp = icmp eq i32 %a, 1
1277  %conv = zext i1 %cmp to i32
1278  %cmp1 = icmp eq i32 %conv, %a
1279  ret i1 %cmp1
1280}
1281
1282define i1 @icmp_eq_zext_ne_one(i32 %a) {
1283; CHECK-LABEL: @icmp_eq_zext_ne_one(
1284; CHECK-NEXT:    ret i1 false
1285;
1286  %cmp = icmp ne i32 %a, 1
1287  %conv = zext i1 %cmp to i32
1288  %cmp1 = icmp eq i32 %conv, %a
1289  ret i1 %cmp1
1290}
1291
1292define i1 @icmp_ne_zext_eq_non_boolean(i32 %a) {
1293; CHECK-LABEL: @icmp_ne_zext_eq_non_boolean(
1294; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 0
1295; CHECK-NEXT:    ret i1 [[CMP1]]
1296;
1297  %cmp = icmp eq i32 %a, 2
1298  %conv = zext i1 %cmp to i32
1299  %cmp1 = icmp ne i32 %conv, %a
1300  ret i1 %cmp1
1301}
1302
1303define i1 @icmp_ne_zext_ne_non_boolean(i32 %a) {
1304; CHECK-LABEL: @icmp_ne_zext_ne_non_boolean(
1305; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 1
1306; CHECK-NEXT:    ret i1 [[CMP1]]
1307;
1308  %cmp = icmp ne i32 %a, 2
1309  %conv = zext i1 %cmp to i32
1310  %cmp1 = icmp ne i32 %conv, %a
1311  ret i1 %cmp1
1312}
1313
1314define i1 @icmp_eq_zext_eq_non_boolean(i32 %a) {
1315; CHECK-LABEL: @icmp_eq_zext_eq_non_boolean(
1316; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 0
1317; CHECK-NEXT:    ret i1 [[CMP1]]
1318;
1319  %cmp = icmp eq i32 %a, 2
1320  %conv = zext i1 %cmp to i32
1321  %cmp1 = icmp eq i32 %conv, %a
1322  ret i1 %cmp1
1323}
1324
1325define i1 @icmp_eq_zext_ne_non_boolean(i32 %a) {
1326; CHECK-LABEL: @icmp_eq_zext_ne_non_boolean(
1327; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 1
1328; CHECK-NEXT:    ret i1 [[CMP1]]
1329;
1330  %cmp = icmp ne i32 %a, 2
1331  %conv = zext i1 %cmp to i32
1332  %cmp1 = icmp eq i32 %conv, %a
1333  ret i1 %cmp1
1334}
1335
1336define <2 x i1> @icmp_ne_zext_eq_zero_vec(<2 x i32> %a) {
1337; CHECK-LABEL: @icmp_ne_zext_eq_zero_vec(
1338; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
1339;
1340  %cmp = icmp eq <2 x i32> %a, <i32 0, i32 0>
1341  %conv = zext <2 x i1> %cmp to <2 x i32>
1342  %cmp1 = icmp ne <2 x i32> %conv, %a
1343  ret <2 x i1> %cmp1
1344}
1345
1346define <2 x i1> @icmp_ne_zext_ne_zero_vec(<2 x i32> %a) {
1347; CHECK-LABEL: @icmp_ne_zext_ne_zero_vec(
1348; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt <2 x i32> [[A:%.*]], splat (i32 1)
1349; CHECK-NEXT:    ret <2 x i1> [[CMP1]]
1350;
1351  %cmp = icmp ne <2 x i32> %a, <i32 0, i32 0>
1352  %conv = zext <2 x i1> %cmp to <2 x i32>
1353  %cmp1 = icmp ne <2 x i32> %conv, %a
1354  ret <2 x i1> %cmp1
1355}
1356
1357define <2 x i1> @icmp_ne_zext_eq_one_vec(<2 x i32> %a) {
1358; CHECK-LABEL: @icmp_ne_zext_eq_one_vec(
1359; CHECK-NEXT:    [[CMP1:%.*]] = icmp ugt <2 x i32> [[A:%.*]], splat (i32 1)
1360; CHECK-NEXT:    ret <2 x i1> [[CMP1]]
1361;
1362  %cmp = icmp eq <2 x i32> %a, <i32 1, i32 1>
1363  %conv = zext <2 x i1> %cmp to <2 x i32>
1364  %cmp1 = icmp ne <2 x i32> %conv, %a
1365  ret <2 x i1> %cmp1
1366}
1367
1368define <2 x i1> @icmp_ne_zext_ne_one_vec(<2 x i32> %a) {
1369; CHECK-LABEL: @icmp_ne_zext_ne_one_vec(
1370; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
1371;
1372  %cmp = icmp ne <2 x i32> %a, <i32 1, i32 1>
1373  %conv = zext <2 x i1> %cmp to <2 x i32>
1374  %cmp1 = icmp ne <2 x i32> %conv, %a
1375  ret <2 x i1> %cmp1
1376}
1377
1378define <2 x i1> @icmp_ne_zext_eq_non_boolean_vec(<2 x i32> %a) {
1379; CHECK-LABEL: @icmp_ne_zext_eq_non_boolean_vec(
1380; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne <2 x i32> [[A:%.*]], zeroinitializer
1381; CHECK-NEXT:    ret <2 x i1> [[CMP1]]
1382;
1383  %cmp = icmp eq <2 x i32> %a, <i32 2, i32 2>
1384  %conv = zext <2 x i1> %cmp to <2 x i32>
1385  %cmp1 = icmp ne <2 x i32> %conv, %a
1386  ret <2 x i1> %cmp1
1387}
1388
1389define i1 @icmp_ne_sext_eq_zero(i32 %a) {
1390; CHECK-LABEL: @icmp_ne_sext_eq_zero(
1391; CHECK-NEXT:    ret i1 true
1392;
1393  %cmp = icmp eq i32 %a, 0
1394  %conv = sext i1 %cmp to i32
1395  %cmp1 = icmp ne i32 %conv, %a
1396  ret i1 %cmp1
1397}
1398
1399define i1 @icmp_ne_sext_ne_zero(i32 %a) {
1400; CHECK-LABEL: @icmp_ne_sext_ne_zero(
1401; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], -1
1402; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[TMP1]], -2
1403; CHECK-NEXT:    ret i1 [[CMP1]]
1404;
1405  %cmp = icmp ne i32 %a, 0
1406  %conv = sext i1 %cmp to i32
1407  %cmp1 = icmp ne i32 %conv, %a
1408  ret i1 %cmp1
1409}
1410
1411define i1 @icmp_eq_sext_eq_zero(i32 %a) {
1412; CHECK-LABEL: @icmp_eq_sext_eq_zero(
1413; CHECK-NEXT:    ret i1 false
1414;
1415  %cmp = icmp eq i32 %a, 0
1416  %conv = sext i1 %cmp to i32
1417  %cmp1 = icmp eq i32 %conv, %a
1418  ret i1 %cmp1
1419}
1420
1421define i1 @icmp_eq_sext_ne_zero(i32 %a) {
1422; CHECK-LABEL: @icmp_eq_sext_ne_zero(
1423; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], 1
1424; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[TMP1]], 2
1425; CHECK-NEXT:    ret i1 [[CMP1]]
1426;
1427  %cmp = icmp ne i32 %a, 0
1428  %conv = sext i1 %cmp to i32
1429  %cmp1 = icmp eq i32 %conv, %a
1430  ret i1 %cmp1
1431}
1432
1433define i1 @icmp_ne_sext_eq_allones(i32 %a) {
1434; CHECK-LABEL: @icmp_ne_sext_eq_allones(
1435; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], -1
1436; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[TMP1]], -2
1437; CHECK-NEXT:    ret i1 [[CMP1]]
1438;
1439  %cmp = icmp eq i32 %a, -1
1440  %conv = sext i1 %cmp to i32
1441  %cmp1 = icmp ne i32 %conv, %a
1442  ret i1 %cmp1
1443}
1444
1445define i1 @icmp_ne_sext_ne_allones(i32 %a) {
1446; CHECK-LABEL: @icmp_ne_sext_ne_allones(
1447; CHECK-NEXT:    ret i1 true
1448;
1449  %cmp = icmp ne i32 %a, -1
1450  %conv = sext i1 %cmp to i32
1451  %cmp1 = icmp ne i32 %conv, %a
1452  ret i1 %cmp1
1453}
1454
1455define i1 @icmp_eq_sext_eq_allones(i32 %a) {
1456; CHECK-LABEL: @icmp_eq_sext_eq_allones(
1457; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], 1
1458; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[TMP1]], 2
1459; CHECK-NEXT:    ret i1 [[CMP1]]
1460;
1461  %cmp = icmp eq i32 %a, -1
1462  %conv = sext i1 %cmp to i32
1463  %cmp1 = icmp eq i32 %conv, %a
1464  ret i1 %cmp1
1465}
1466
1467define i1 @icmp_eq_sext_ne_allones(i32 %a) {
1468; CHECK-LABEL: @icmp_eq_sext_ne_allones(
1469; CHECK-NEXT:    ret i1 false
1470;
1471  %cmp = icmp ne i32 %a, -1
1472  %conv = sext i1 %cmp to i32
1473  %cmp1 = icmp eq i32 %conv, %a
1474  ret i1 %cmp1
1475}
1476
1477define i1 @icmp_ne_sext_eq_otherwise(i32 %a) {
1478; CHECK-LABEL: @icmp_ne_sext_eq_otherwise(
1479; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], 0
1480; CHECK-NEXT:    ret i1 [[CMP1]]
1481;
1482  %cmp = icmp eq i32 %a, 2
1483  %conv = sext i1 %cmp to i32
1484  %cmp1 = icmp ne i32 %conv, %a
1485  ret i1 %cmp1
1486}
1487
1488define i1 @icmp_ne_sext_ne_otherwise(i32 %a) {
1489; CHECK-LABEL: @icmp_ne_sext_ne_otherwise(
1490; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A:%.*]], -1
1491; CHECK-NEXT:    ret i1 [[CMP1]]
1492;
1493  %cmp = icmp ne i32 %a, 2
1494  %conv = sext i1 %cmp to i32
1495  %cmp1 = icmp ne i32 %conv, %a
1496  ret i1 %cmp1
1497}
1498
1499define i1 @icmp_eq_sext_eq_otherwise(i32 %a) {
1500; CHECK-LABEL: @icmp_eq_sext_eq_otherwise(
1501; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], 0
1502; CHECK-NEXT:    ret i1 [[CMP1]]
1503;
1504  %cmp = icmp eq i32 %a, 2
1505  %conv = sext i1 %cmp to i32
1506  %cmp1 = icmp eq i32 %conv, %a
1507  ret i1 %cmp1
1508}
1509
1510define i1 @icmp_eq_sext_ne_otherwise(i32 %a) {
1511; CHECK-LABEL: @icmp_eq_sext_ne_otherwise(
1512; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i32 [[A:%.*]], -1
1513; CHECK-NEXT:    ret i1 [[CMP1]]
1514;
1515  %cmp = icmp ne i32 %a, 2
1516  %conv = sext i1 %cmp to i32
1517  %cmp1 = icmp eq i32 %conv, %a
1518  ret i1 %cmp1
1519}
1520
1521define <2 x i1> @icmp_ne_sext_eq_zero_vec(<2 x i32> %a) {
1522; CHECK-LABEL: @icmp_ne_sext_eq_zero_vec(
1523; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
1524;
1525  %cmp = icmp eq <2 x i32> %a, <i32 0, i32 0>
1526  %conv = sext <2 x i1> %cmp to <2 x i32>
1527  %cmp1 = icmp ne <2 x i32> %conv, %a
1528  ret <2 x i1> %cmp1
1529}
1530
1531define <2 x i1> @icmp_ne_sext_ne_zero_vec(<2 x i32> %a) {
1532; CHECK-LABEL: @icmp_ne_sext_ne_zero_vec(
1533; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 -1)
1534; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 -2)
1535; CHECK-NEXT:    ret <2 x i1> [[CMP1]]
1536;
1537  %cmp = icmp ne <2 x i32> %a, <i32 0, i32 0>
1538  %conv = sext <2 x i1> %cmp to <2 x i32>
1539  %cmp1 = icmp ne <2 x i32> %conv, %a
1540  ret <2 x i1> %cmp1
1541}
1542
1543define <2 x i1> @icmp_ne_sext_eq_allones_vec(<2 x i32> %a) {
1544; CHECK-LABEL: @icmp_ne_sext_eq_allones_vec(
1545; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 -1)
1546; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 -2)
1547; CHECK-NEXT:    ret <2 x i1> [[CMP1]]
1548;
1549  %cmp = icmp eq <2 x i32> %a, <i32 -1, i32 -1>
1550  %conv = sext <2 x i1> %cmp to <2 x i32>
1551  %cmp1 = icmp ne <2 x i32> %conv, %a
1552  ret <2 x i1> %cmp1
1553}
1554
1555define <2 x i1> @icmp_ne_sext_ne_allones_vec(<2 x i32> %a) {
1556; CHECK-LABEL: @icmp_ne_sext_ne_allones_vec(
1557; CHECK-NEXT:    ret <2 x i1> splat (i1 true)
1558;
1559  %cmp = icmp ne <2 x i32> %a, <i32 -1, i32 -1>
1560  %conv = sext <2 x i1> %cmp to <2 x i32>
1561  %cmp1 = icmp ne <2 x i32> %conv, %a
1562  ret <2 x i1> %cmp1
1563}
1564
1565define <2 x i1> @icmp_ne_sext_eq_otherwise_vec(<2 x i32> %a) {
1566; CHECK-LABEL: @icmp_ne_sext_eq_otherwise_vec(
1567; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne <2 x i32> [[A:%.*]], zeroinitializer
1568; CHECK-NEXT:    ret <2 x i1> [[CMP1]]
1569;
1570  %cmp = icmp eq <2 x i32> %a, <i32 2, i32 2>
1571  %conv = sext <2 x i1> %cmp to <2 x i32>
1572  %cmp1 = icmp ne <2 x i32> %conv, %a
1573  ret <2 x i1> %cmp1
1574}
1575
1576define i1 @icmp_ne_sext_ne_zero_i128(i128 %a) {
1577; CHECK-LABEL: @icmp_ne_sext_ne_zero_i128(
1578; CHECK-NEXT:    [[TMP1:%.*]] = add i128 [[A:%.*]], -1
1579; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i128 [[TMP1]], -2
1580; CHECK-NEXT:    ret i1 [[CMP1]]
1581;
1582  %cmp = icmp ne i128 %a, 0
1583  %conv = sext i1 %cmp to i128
1584  %cmp1 = icmp ne i128 %conv, %a
1585  ret i1 %cmp1
1586}
1587
1588define i1 @icmp_ne_sext_ne_otherwise_i128(i128 %a) {
1589; CHECK-LABEL: @icmp_ne_sext_ne_otherwise_i128(
1590; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i128 [[A:%.*]], -1
1591; CHECK-NEXT:    ret i1 [[CMP1]]
1592;
1593  %cmp = icmp ne i128 %a, 2
1594  %conv = sext i1 %cmp to i128
1595  %cmp1 = icmp ne i128 %conv, %a
1596  ret i1 %cmp1
1597}
1598
1599; Negative tests with non-equality predicates
1600define i1 @icmp_ne_sext_sgt_zero_nofold(i32 %a) {
1601; CHECK-LABEL: @icmp_ne_sext_sgt_zero_nofold(
1602; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0
1603; CHECK-NEXT:    [[CONV:%.*]] = sext i1 [[CMP]] to i32
1604; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A]], [[CONV]]
1605; CHECK-NEXT:    ret i1 [[CMP1]]
1606;
1607  %cmp = icmp sgt i32 %a, 0
1608  %conv = sext i1 %cmp to i32
1609  %cmp1 = icmp ne i32 %conv, %a
1610  ret i1 %cmp1
1611}
1612
1613define i1 @icmp_slt_sext_ne_zero_nofold(i32 %a) {
1614; CHECK-LABEL: @icmp_slt_sext_ne_zero_nofold(
1615; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[A:%.*]], 0
1616; CHECK-NEXT:    [[CONV:%.*]] = sext i1 [[CMP]] to i32
1617; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A]], [[CONV]]
1618; CHECK-NEXT:    ret i1 [[CMP1]]
1619;
1620  %cmp = icmp ne i32 %a, 0
1621  %conv = sext i1 %cmp to i32
1622  %cmp1 = icmp slt i32 %conv, %a
1623  ret i1 %cmp1
1624}
1625
1626define i1 @icmp_ne_sext_slt_allones_nofold(i32 %a) {
1627; CHECK-LABEL: @icmp_ne_sext_slt_allones_nofold(
1628; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], -1
1629; CHECK-NEXT:    [[CONV:%.*]] = sext i1 [[CMP]] to i32
1630; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A]], [[CONV]]
1631; CHECK-NEXT:    ret i1 [[CMP1]]
1632;
1633  %cmp = icmp slt i32 %a, -1
1634  %conv = sext i1 %cmp to i32
1635  %cmp1 = icmp ne i32 %conv, %a
1636  ret i1 %cmp1
1637}
1638
1639define i1 @icmp_slt_sext_ne_allones_nofold(i32 %a) {
1640; CHECK-LABEL: @icmp_slt_sext_ne_allones_nofold(
1641; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[A:%.*]], -1
1642; CHECK-NEXT:    [[CONV:%.*]] = sext i1 [[CMP]] to i32
1643; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A]], [[CONV]]
1644; CHECK-NEXT:    ret i1 [[CMP1]]
1645;
1646  %cmp = icmp ne i32 %a, -1
1647  %conv = sext i1 %cmp to i32
1648  %cmp1 = icmp slt i32 %conv, %a
1649  ret i1 %cmp1
1650}
1651
1652define i1 @icmp_ne_sext_slt_otherwise_nofold(i32 %a) {
1653; CHECK-LABEL: @icmp_ne_sext_slt_otherwise_nofold(
1654; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 2
1655; CHECK-NEXT:    [[CONV:%.*]] = sext i1 [[CMP]] to i32
1656; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[A]], [[CONV]]
1657; CHECK-NEXT:    ret i1 [[CMP1]]
1658;
1659  %cmp = icmp slt i32 %a, 2
1660  %conv = sext i1 %cmp to i32
1661  %cmp1 = icmp ne i32 %conv, %a
1662  ret i1 %cmp1
1663}
1664
1665define i1 @icmp_slt_sext_ne_otherwise_nofold(i32 %a) {
1666; CHECK-LABEL: @icmp_slt_sext_ne_otherwise_nofold(
1667; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[A:%.*]], 2
1668; CHECK-NEXT:    [[CONV:%.*]] = sext i1 [[CMP]] to i32
1669; CHECK-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A]], [[CONV]]
1670; CHECK-NEXT:    ret i1 [[CMP1]]
1671;
1672  %cmp = icmp ne i32 %a, 2
1673  %conv = sext i1 %cmp to i32
1674  %cmp1 = icmp slt i32 %conv, %a
1675  ret i1 %cmp1
1676}
1677
1678; tests from PR59555
1679define i1 @isFloat(i64 %0) {
1680; CHECK-LABEL: @isFloat(
1681; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i64 [[TMP0:%.*]], 281474976710655
1682; CHECK-NEXT:    [[TMP3:%.*]] = and i64 [[TMP0]], -281474976710656
1683; CHECK-NEXT:    [[TMP4:%.*]] = icmp ne i64 [[TMP3]], 281474976710656
1684; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP2]], [[TMP4]]
1685; CHECK-NEXT:    ret i1 [[TMP5]]
1686;
1687  %2 = icmp ugt i64 %0, 281474976710655
1688  %3 = and i64 %0, -281474976710656
1689  %4 = icmp ne i64 %3, 281474976710656
1690  %5 = and i1 %2, %4
1691  ret i1 %5
1692}
1693
1694!0 = !{i32 1, i32 6}
1695!1 = !{i32 0, i32 6}
1696!2 = !{i8 0, i8 1}
1697!3 = !{i8 0, i8 6}
1698!4 = !{i32 1, i32 6, i32 8, i32 10}
1699!5 = !{i32 5, i32 10}
1700!6 = !{i32 8, i32 16}
1701