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