1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; This test makes sure that all icmp instructions are eliminated.
3; RUN: opt < %s -instcombine -S | FileCheck %s
4
5@X = external global i32
6
7define i1 @test1(i32 %A) {
8; CHECK-LABEL: @test1(
9; CHECK-NEXT:    ret i1 false
10;
11  %B = icmp eq i32 %A, %A
12  ; Never true
13  %C = icmp eq i32* @X, null
14  %D = and i1 %B, %C
15  ret i1 %D
16}
17
18define i1 @test1_logical(i32 %A) {
19; CHECK-LABEL: @test1_logical(
20; CHECK-NEXT:    ret i1 false
21;
22  %B = icmp eq i32 %A, %A
23  ; Never true
24  %C = icmp eq i32* @X, null
25  %D = select i1 %B, i1 %C, i1 false
26  ret i1 %D
27}
28
29define i1 @test2(i32 %A) {
30; CHECK-LABEL: @test2(
31; CHECK-NEXT:    ret i1 true
32;
33  %B = icmp ne i32 %A, %A
34  ; Never false
35  %C = icmp ne i32* @X, null
36  %D = or i1 %B, %C
37  ret i1 %D
38}
39
40define i1 @test2_logical(i32 %A) {
41; CHECK-LABEL: @test2_logical(
42; CHECK-NEXT:    ret i1 true
43;
44  %B = icmp ne i32 %A, %A
45  ; Never false
46  %C = icmp ne i32* @X, null
47  %D = select i1 %B, i1 true, i1 %C
48  ret i1 %D
49}
50
51define i1 @test3(i32 %A) {
52; CHECK-LABEL: @test3(
53; CHECK-NEXT:    ret i1 false
54;
55  %B = icmp slt i32 %A, %A
56  ret i1 %B
57}
58
59
60define i1 @test4(i32 %A) {
61; CHECK-LABEL: @test4(
62; CHECK-NEXT:    ret i1 false
63;
64  %B = icmp sgt i32 %A, %A
65  ret i1 %B
66}
67
68define i1 @test5(i32 %A) {
69; CHECK-LABEL: @test5(
70; CHECK-NEXT:    ret i1 true
71;
72  %B = icmp sle i32 %A, %A
73  ret i1 %B
74}
75
76define i1 @test6(i32 %A) {
77; CHECK-LABEL: @test6(
78; CHECK-NEXT:    ret i1 true
79;
80  %B = icmp sge i32 %A, %A
81  ret i1 %B
82}
83
84define i1 @test7(i32 %A) {
85; CHECK-LABEL: @test7(
86; CHECK-NEXT:    ret i1 true
87;
88  %B = icmp uge i32 %A, 0
89  ret i1 %B
90}
91
92define i1 @test8(i32 %A) {
93; CHECK-LABEL: @test8(
94; CHECK-NEXT:    ret i1 false
95;
96  %B = icmp ult i32 %A, 0
97  ret i1 %B
98}
99
100;; test operations on boolean values these should all be eliminated$a
101define i1 @test9(i1 %A) {
102; CHECK-LABEL: @test9(
103; CHECK-NEXT:    ret i1 false
104;
105  %B = icmp ult i1 %A, false
106  ret i1 %B
107}
108
109define i1 @test10(i1 %A) {
110; CHECK-LABEL: @test10(
111; CHECK-NEXT:    ret i1 false
112;
113  %B = icmp ugt i1 %A, true
114  ret i1 %B
115}
116
117define i1 @test11(i1 %A) {
118; CHECK-LABEL: @test11(
119; CHECK-NEXT:    ret i1 true
120;
121  %B = icmp ule i1 %A, true
122  ret i1 %B
123}
124
125define i1 @test12(i1 %A) {
126; CHECK-LABEL: @test12(
127; CHECK-NEXT:    ret i1 true
128;
129  %B = icmp uge i1 %A, false
130  ret i1 %B
131}
132
133define i1 @test13(i1 %A, i1 %B) {
134; CHECK-LABEL: @test13(
135; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[B:%.*]], true
136; CHECK-NEXT:    [[C:%.*]] = or i1 [[TMP1]], [[A:%.*]]
137; CHECK-NEXT:    ret i1 [[C]]
138;
139  %C = icmp uge i1 %A, %B
140  ret i1 %C
141}
142
143define <2 x i1> @test13vec(<2 x i1> %A, <2 x i1> %B) {
144; CHECK-LABEL: @test13vec(
145; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i1> [[B:%.*]], <i1 true, i1 true>
146; CHECK-NEXT:    [[C:%.*]] = or <2 x i1> [[TMP1]], [[A:%.*]]
147; CHECK-NEXT:    ret <2 x i1> [[C]]
148;
149  %C = icmp uge <2 x i1> %A, %B
150  ret <2 x i1> %C
151}
152
153define i1 @test14(i1 %A, i1 %B) {
154; CHECK-LABEL: @test14(
155; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[A:%.*]], [[B:%.*]]
156; CHECK-NEXT:    [[C:%.*]] = xor i1 [[TMP1]], true
157; CHECK-NEXT:    ret i1 [[C]]
158;
159  %C = icmp eq i1 %A, %B
160  ret i1 %C
161}
162
163define <3 x i1> @test14vec(<3 x i1> %A, <3 x i1> %B) {
164; CHECK-LABEL: @test14vec(
165; CHECK-NEXT:    [[TMP1:%.*]] = xor <3 x i1> [[A:%.*]], [[B:%.*]]
166; CHECK-NEXT:    [[C:%.*]] = xor <3 x i1> [[TMP1]], <i1 true, i1 true, i1 true>
167; CHECK-NEXT:    ret <3 x i1> [[C]]
168;
169  %C = icmp eq <3 x i1> %A, %B
170  ret <3 x i1> %C
171}
172
173define i1 @bool_eq0(i64 %a) {
174; CHECK-LABEL: @bool_eq0(
175; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[A:%.*]], 1
176; CHECK-NEXT:    ret i1 [[TMP1]]
177;
178  %b = icmp sgt i64 %a, 0
179  %c = icmp eq i64 %a, 1
180  %notc = icmp eq i1 %c, false
181  %and = and i1 %b, %notc
182  ret i1 %and
183}
184
185define i1 @bool_eq0_logical(i64 %a) {
186; CHECK-LABEL: @bool_eq0_logical(
187; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[A:%.*]], 1
188; CHECK-NEXT:    ret i1 [[TMP1]]
189;
190  %b = icmp sgt i64 %a, 0
191  %c = icmp eq i64 %a, 1
192  %notc = icmp eq i1 %c, false
193  %and = select i1 %b, i1 %notc, i1 false
194  ret i1 %and
195}
196
197; This is equivalent to the previous test.
198
199define i1 @xor_of_icmps(i64 %a) {
200; CHECK-LABEL: @xor_of_icmps(
201; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[A:%.*]], 1
202; CHECK-NEXT:    ret i1 [[TMP1]]
203;
204  %b = icmp sgt i64 %a, 0
205  %c = icmp eq i64 %a, 1
206  %xor = xor i1 %c, %b
207  ret i1 %xor
208}
209
210; This is also equivalent to the previous test.
211
212define i1 @xor_of_icmps_commute(i64 %a) {
213; CHECK-LABEL: @xor_of_icmps_commute(
214; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[A:%.*]], 1
215; CHECK-NEXT:    ret i1 [[TMP1]]
216;
217  %b = icmp sgt i64 %a, 0
218  %c = icmp eq i64 %a, 1
219  %xor = xor i1 %b, %c
220  ret i1 %xor
221}
222
223; FIXME: This is (a != 5).
224
225define i1 @xor_of_icmps_folds_more(i64 %a) {
226; CHECK-LABEL: @xor_of_icmps_folds_more(
227; CHECK-NEXT:    [[B:%.*]] = icmp sgt i64 [[A:%.*]], 4
228; CHECK-NEXT:    [[C:%.*]] = icmp slt i64 [[A]], 6
229; CHECK-NEXT:    [[XOR:%.*]] = xor i1 [[B]], [[C]]
230; CHECK-NEXT:    ret i1 [[XOR]]
231;
232  %b = icmp sgt i64 %a, 4
233  %c = icmp slt i64 %a, 6
234  %xor = xor i1 %b, %c
235  ret i1 %xor
236}
237
238; https://bugs.llvm.org/show_bug.cgi?id=2844
239
240define i32 @PR2844(i32 %x) {
241; CHECK-LABEL: @PR2844(
242; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
243; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[X]], -638208502
244; CHECK-NEXT:    [[NOT_OR:%.*]] = and i1 [[A]], [[B]]
245; CHECK-NEXT:    [[SEL:%.*]] = zext i1 [[NOT_OR]] to i32
246; CHECK-NEXT:    ret i32 [[SEL]]
247;
248  %A = icmp eq i32 %x, 0
249  %B = icmp slt i32 %x, -638208501
250  %or = or i1 %A, %B
251  %sel = select i1 %or, i32 0, i32 1
252  ret i32 %sel
253}
254
255define i32 @PR2844_logical(i32 %x) {
256; CHECK-LABEL: @PR2844_logical(
257; CHECK-NEXT:    [[A:%.*]] = icmp ne i32 [[X:%.*]], 0
258; CHECK-NEXT:    [[B:%.*]] = icmp sgt i32 [[X]], -638208502
259; CHECK-NEXT:    [[NOT_OR:%.*]] = and i1 [[A]], [[B]]
260; CHECK-NEXT:    [[SEL:%.*]] = zext i1 [[NOT_OR]] to i32
261; CHECK-NEXT:    ret i32 [[SEL]]
262;
263  %A = icmp eq i32 %x, 0
264  %B = icmp slt i32 %x, -638208501
265  %or = select i1 %A, i1 true, i1 %B
266  %sel = select i1 %or, i32 0, i32 1
267  ret i32 %sel
268}
269
270define i1 @test16(i32 %A) {
271; CHECK-LABEL: @test16(
272; CHECK-NEXT:    ret i1 false
273;
274  %B = and i32 %A, 5
275  ; Is never true
276  %C = icmp eq i32 %B, 8
277  ret i1 %C
278}
279
280define i1 @test17(i8 %A) {
281; CHECK-LABEL: @test17(
282; CHECK-NEXT:    ret i1 false
283;
284  %B = or i8 %A, 1
285  ; Always false
286  %C = icmp eq i8 %B, 2
287  ret i1 %C
288}
289
290define i1 @test18(i1 %C, i32 %a) {
291; CHECK-LABEL: @test18(
292; CHECK-NEXT:  entry:
293; CHECK-NEXT:    br i1 [[C:%.*]], label [[ENDIF:%.*]], label [[ELSE:%.*]]
294; CHECK:       else:
295; CHECK-NEXT:    br label [[ENDIF]]
296; CHECK:       endif:
297; CHECK-NEXT:    ret i1 true
298;
299entry:
300  br i1 %C, label %endif, label %else
301
302else:
303  br label %endif
304
305endif:
306  %b.0 = phi i32 [ 0, %entry ], [ 1, %else ]
307  %tmp.4 = icmp slt i32 %b.0, 123
308  ret i1 %tmp.4
309}
310
311define i1 @test19(i1 %A, i1 %B) {
312; CHECK-LABEL: @test19(
313; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[A:%.*]], [[B:%.*]]
314; CHECK-NEXT:    [[C:%.*]] = xor i1 [[TMP1]], true
315; CHECK-NEXT:    ret i1 [[C]]
316;
317  %a = zext i1 %A to i32
318  %b = zext i1 %B to i32
319  %C = icmp eq i32 %a, %b
320  ret i1 %C
321}
322
323define i32 @test20(i32 %A) {
324; CHECK-LABEL: @test20(
325; CHECK-NEXT:    [[B:%.*]] = and i32 [[A:%.*]], 1
326; CHECK-NEXT:    ret i32 [[B]]
327;
328  %B = and i32 %A, 1
329  %C = icmp ne i32 %B, 0
330  %D = zext i1 %C to i32
331  ret i32 %D
332}
333
334define <2 x i32> @test20vec(<2 x i32> %A) {
335; CHECK-LABEL: @test20vec(
336; CHECK-NEXT:    [[D:%.*]] = and <2 x i32> [[A:%.*]], <i32 1, i32 1>
337; CHECK-NEXT:    ret <2 x i32> [[D]]
338;
339  %B = and <2 x i32> %A, <i32 1, i32 1>
340  %C = icmp ne <2 x i32> %B, zeroinitializer
341  %D = zext <2 x i1> %C to <2 x i32>
342  ret <2 x i32> %D
343}
344
345define i32 @test21(i32 %a) {
346; CHECK-LABEL: @test21(
347; CHECK-NEXT:    [[TMP_6:%.*]] = lshr i32 [[A:%.*]], 2
348; CHECK-NEXT:    [[TMP_6_LOBIT:%.*]] = and i32 [[TMP_6]], 1
349; CHECK-NEXT:    ret i32 [[TMP_6_LOBIT]]
350;
351  %tmp.6 = and i32 %a, 4
352  %not.tmp.7 = icmp ne i32 %tmp.6, 0
353  %retval = zext i1 %not.tmp.7 to i32
354  ret i32 %retval
355}
356
357define <2 x i32> @test21vec(<2 x i32> %a) {
358; CHECK-LABEL: @test21vec(
359; CHECK-NEXT:    [[TMP_6:%.*]] = lshr <2 x i32> [[A:%.*]], <i32 2, i32 2>
360; CHECK-NEXT:    [[TMP_6_LOBIT:%.*]] = and <2 x i32> [[TMP_6]], <i32 1, i32 1>
361; CHECK-NEXT:    ret <2 x i32> [[TMP_6_LOBIT]]
362;
363  %tmp.6 = and <2 x i32> %a, <i32 4, i32 4>
364  %not.tmp.7 = icmp ne <2 x i32> %tmp.6, zeroinitializer
365  %retval = zext <2 x i1> %not.tmp.7 to <2 x i32>
366  ret <2 x i32> %retval
367}
368
369define i1 @test22(i32 %A, i32 %X) {
370; CHECK-LABEL: @test22(
371; CHECK-NEXT:    ret i1 true
372;
373  %B = and i32 %A, 100663295
374  %C = icmp ult i32 %B, 268435456
375  %Y = and i32 %X, 7
376  %Z = icmp sgt i32 %Y, -1
377  %R = or i1 %C, %Z
378  ret i1 %R
379}
380
381define i1 @test22_logical(i32 %A, i32 %X) {
382; CHECK-LABEL: @test22_logical(
383; CHECK-NEXT:    ret i1 true
384;
385  %B = and i32 %A, 100663295
386  %C = icmp ult i32 %B, 268435456
387  %Y = and i32 %X, 7
388  %Z = icmp sgt i32 %Y, -1
389  %R = select i1 %C, i1 true, i1 %Z
390  ret i1 %R
391}
392
393define i32 @test23(i32 %a) {
394; CHECK-LABEL: @test23(
395; CHECK-NEXT:    [[TMP_1:%.*]] = and i32 [[A:%.*]], 1
396; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[TMP_1]], 1
397; CHECK-NEXT:    ret i32 [[TMP1]]
398;
399  %tmp.1 = and i32 %a, 1
400  %tmp.2 = icmp eq i32 %tmp.1, 0
401  %tmp.3 = zext i1 %tmp.2 to i32
402  ret i32 %tmp.3
403}
404
405define <2 x i32> @test23vec(<2 x i32> %a) {
406; CHECK-LABEL: @test23vec(
407; CHECK-NEXT:    [[TMP_1:%.*]] = and <2 x i32> [[A:%.*]], <i32 1, i32 1>
408; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[TMP_1]], <i32 1, i32 1>
409; CHECK-NEXT:    ret <2 x i32> [[TMP1]]
410;
411  %tmp.1 = and <2 x i32> %a, <i32 1, i32 1>
412  %tmp.2 = icmp eq <2 x i32> %tmp.1, zeroinitializer
413  %tmp.3 = zext <2 x i1> %tmp.2 to <2 x i32>
414  ret <2 x i32> %tmp.3
415}
416
417define i32 @test24(i32 %a) {
418; CHECK-LABEL: @test24(
419; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[A:%.*]], 2
420; CHECK-NEXT:    [[DOTLOBIT:%.*]] = and i32 [[TMP1]], 1
421; CHECK-NEXT:    [[TMP2:%.*]] = xor i32 [[DOTLOBIT]], 1
422; CHECK-NEXT:    ret i32 [[TMP2]]
423;
424  %tmp1 = and i32 %a, 4
425  %tmp.1 = lshr i32 %tmp1, 2
426  %tmp.2 = icmp eq i32 %tmp.1, 0
427  %tmp.3 = zext i1 %tmp.2 to i32
428  ret i32 %tmp.3
429}
430
431define <2 x i32> @test24vec(<2 x i32> %a) {
432; CHECK-LABEL: @test24vec(
433; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[A:%.*]], <i32 2, i32 2>
434; CHECK-NEXT:    [[DOTLOBIT:%.*]] = and <2 x i32> [[TMP1]], <i32 1, i32 1>
435; CHECK-NEXT:    [[TMP2:%.*]] = xor <2 x i32> [[DOTLOBIT]], <i32 1, i32 1>
436; CHECK-NEXT:    ret <2 x i32> [[TMP2]]
437;
438  %tmp1 = and <2 x i32> %a, <i32 4, i32 4>
439  %tmp.1 = lshr <2 x i32> %tmp1, <i32 2, i32 2>
440  %tmp.2 = icmp eq <2 x i32> %tmp.1, zeroinitializer
441  %tmp.3 = zext <2 x i1> %tmp.2 to <2 x i32>
442  ret <2 x i32> %tmp.3
443}
444
445define i1 @test25(i32 %A) {
446; CHECK-LABEL: @test25(
447; CHECK-NEXT:    ret i1 false
448;
449  %B = and i32 %A, 2
450  %C = icmp ugt i32 %B, 2
451  ret i1 %C
452}
453
454