xref: /llvm-project/llvm/test/Transforms/InstCombine/and-compare.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
4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5target triple = "x86_64-unknown-linux-gnu"
6
7declare void @use.i8(i8)
8
9; Should be optimized to one and.
10define i1 @test1(i32 %a, i32 %b) {
11; CHECK-LABEL: @test1(
12; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
13; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], 65280
14; CHECK-NEXT:    [[TMP:%.*]] = icmp ne i32 [[TMP2]], 0
15; CHECK-NEXT:    ret i1 [[TMP]]
16;
17  %tmp1 = and i32 %a, 65280
18  %tmp3 = and i32 %b, 65280
19  %tmp = icmp ne i32 %tmp1, %tmp3
20  ret i1 %tmp
21}
22
23define <2 x i1> @test1vec(<2 x i32> %a, <2 x i32> %b) {
24; CHECK-LABEL: @test1vec(
25; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i32> [[A:%.*]], [[B:%.*]]
26; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], splat (i32 65280)
27; CHECK-NEXT:    [[TMP:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
28; CHECK-NEXT:    ret <2 x i1> [[TMP]]
29;
30  %tmp1 = and <2 x i32> %a, <i32 65280, i32 65280>
31  %tmp3 = and <2 x i32> %b, <i32 65280, i32 65280>
32  %tmp = icmp ne <2 x i32> %tmp1, %tmp3
33  ret <2 x i1> %tmp
34}
35
36define i1 @test2(i64 %A) {
37; CHECK-LABEL: @test2(
38; CHECK-NEXT:    [[AND:%.*]] = and i64 [[A:%.*]], 128
39; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i64 [[AND]], 0
40; CHECK-NEXT:    ret i1 [[CMP]]
41;
42  %and = and i64 %A, 128
43  %cmp = icmp eq i64 %and, 0
44  ret i1 %cmp
45}
46
47define <2 x i1> @test2vec(<2 x i64> %A) {
48; CHECK-LABEL: @test2vec(
49; CHECK-NEXT:    [[AND:%.*]] = and <2 x i64> [[A:%.*]], splat (i64 128)
50; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i64> [[AND]], zeroinitializer
51; CHECK-NEXT:    ret <2 x i1> [[CMP]]
52;
53  %and = and <2 x i64> %A, <i64 128, i64 128>
54  %cmp = icmp eq <2 x i64> %and, zeroinitializer
55  ret <2 x i1> %cmp
56}
57
58define i1 @test3(i64 %A) {
59; CHECK-LABEL: @test3(
60; CHECK-NEXT:    [[AND:%.*]] = and i64 [[A:%.*]], 128
61; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i64 [[AND]], 0
62; CHECK-NEXT:    ret i1 [[CMP]]
63;
64  %and = and i64 %A, 128
65  %cmp = icmp ne i64 %and, 0
66  ret i1 %cmp
67}
68
69define <2 x i1> @test3vec(<2 x i64> %A) {
70; CHECK-LABEL: @test3vec(
71; CHECK-NEXT:    [[AND:%.*]] = and <2 x i64> [[A:%.*]], splat (i64 128)
72; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i64> [[AND]], zeroinitializer
73; CHECK-NEXT:    ret <2 x i1> [[CMP]]
74;
75  %and = and <2 x i64> %A, <i64 128, i64 128>
76  %cmp = icmp ne <2 x i64> %and, zeroinitializer
77  ret <2 x i1> %cmp
78}
79
80define i1 @test_ne_cp2(i8 %x, i8 %yy) {
81; CHECK-LABEL: @test_ne_cp2(
82; CHECK-NEXT:    [[AND_X_NEG_Y:%.*]] = and i8 [[X:%.*]], -16
83; CHECK-NEXT:    [[AND_X_Y:%.*]] = and i8 [[X]], 16
84; CHECK-NEXT:    call void @use.i8(i8 [[AND_X_NEG_Y]])
85; CHECK-NEXT:    call void @use.i8(i8 [[AND_X_Y]])
86; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[X]], 31
87; CHECK-NEXT:    ret i1 [[R]]
88;
89  %and_x_neg_y = and i8 %x, -16
90  %and_x_y = and i8 %x, 16
91  call void @use.i8(i8 %and_x_neg_y)
92  call void @use.i8(i8 %and_x_y)
93  %r = icmp ne i8 %and_x_neg_y, %and_x_y
94  ret i1 %r
95}
96
97define i1 @test_ne_cp2_2(i8 %x, i8 %yy) {
98; CHECK-LABEL: @test_ne_cp2_2(
99; CHECK-NEXT:    [[AND_X_NEG_Y:%.*]] = and i8 [[X:%.*]], -4
100; CHECK-NEXT:    [[AND_X_Y:%.*]] = and i8 [[X]], 4
101; CHECK-NEXT:    call void @use.i8(i8 [[AND_X_NEG_Y]])
102; CHECK-NEXT:    call void @use.i8(i8 [[AND_X_Y]])
103; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[X]], 8
104; CHECK-NEXT:    ret i1 [[R]]
105;
106  %and_x_neg_y = and i8 %x, -4
107  %and_x_y = and i8 %x, 4
108  call void @use.i8(i8 %and_x_neg_y)
109  call void @use.i8(i8 %and_x_y)
110  %r = icmp eq i8 %and_x_y, %and_x_neg_y
111  ret i1 %r
112}
113
114define i1 @test_ne_cp2_other_okay_all_ones(i8 %x, i8 %yy) {
115; CHECK-LABEL: @test_ne_cp2_other_okay_all_ones(
116; CHECK-NEXT:    [[AND_X_NEG_Y:%.*]] = and i8 [[X:%.*]], -17
117; CHECK-NEXT:    [[AND_X_Y:%.*]] = and i8 [[X]], 16
118; CHECK-NEXT:    call void @use.i8(i8 [[AND_X_NEG_Y]])
119; CHECK-NEXT:    call void @use.i8(i8 [[AND_X_Y]])
120; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X]], 0
121; CHECK-NEXT:    ret i1 [[R]]
122;
123  %and_x_neg_y = and i8 %x, -17
124  %and_x_y = and i8 %x, 16
125  call void @use.i8(i8 %and_x_neg_y)
126  call void @use.i8(i8 %and_x_y)
127  %r = icmp ne i8 %and_x_neg_y, %and_x_y
128  ret i1 %r
129}
130
131define i1 @test_ne_cp2_other_fail2(i8 %x, i8 %yy) {
132; CHECK-LABEL: @test_ne_cp2_other_fail2(
133; CHECK-NEXT:    [[AND_X_NEG_Y:%.*]] = and i8 [[X:%.*]], -16
134; CHECK-NEXT:    [[AND_X_Y:%.*]] = and i8 [[X]], 17
135; CHECK-NEXT:    call void @use.i8(i8 [[AND_X_NEG_Y]])
136; CHECK-NEXT:    call void @use.i8(i8 [[AND_X_Y]])
137; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[AND_X_NEG_Y]], [[AND_X_Y]]
138; CHECK-NEXT:    ret i1 [[R]]
139;
140  %and_x_neg_y = and i8 %x, -16
141  %and_x_y = and i8 %x, 17
142  call void @use.i8(i8 %and_x_neg_y)
143  call void @use.i8(i8 %and_x_y)
144  %r = icmp ne i8 %and_x_neg_y, %and_x_y
145  ret i1 %r
146}
147
148define i1 @test_ne_cp2_other_okay(i8 %x, i8 %yy) {
149; CHECK-LABEL: @test_ne_cp2_other_okay(
150; CHECK-NEXT:    [[AND_X_Y:%.*]] = and i8 [[X:%.*]], 16
151; CHECK-NEXT:    call void @use.i8(i8 [[AND_X_Y]])
152; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X]], 0
153; CHECK-NEXT:    ret i1 [[R]]
154;
155  %and_x_neg_y = and i8 %x, -17
156  %and_x_y = and i8 %x, 16
157  call void @use.i8(i8 %and_x_y)
158  %r = icmp ne i8 %and_x_neg_y, %and_x_y
159  ret i1 %r
160}
161
162define i1 @test_ne_cp2_other_okay2(i8 %x, i8 %yy) {
163; CHECK-LABEL: @test_ne_cp2_other_okay2(
164; CHECK-NEXT:    [[AND_X_Y:%.*]] = and i8 [[X:%.*]], 16
165; CHECK-NEXT:    call void @use.i8(i8 [[AND_X_Y]])
166; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[X]], 0
167; CHECK-NEXT:    ret i1 [[R]]
168;
169  %and_x_neg_y = and i8 %x, -17
170  %and_x_y = and i8 %x, 16
171  call void @use.i8(i8 %and_x_y)
172  %r = icmp ne i8 %and_x_y, %and_x_neg_y
173  ret i1 %r
174}
175
176define i1 @test_eq_0_and_15_add_1(i8 %a) {
177; CHECK-LABEL: @test_eq_0_and_15_add_1(
178; CHECK-NEXT:  entry:
179; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[A:%.*]], 15
180; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[TMP0]], 15
181; CHECK-NEXT:    ret i1 [[CMP]]
182;
183entry:
184  %add = add i8 %a, 1
185  %and = and i8 %add, 15
186  %cmp = icmp eq i8 %and, 0
187  ret i1 %cmp
188}
189
190define i1 @test_ne_0_and_15_add_1(i8 %a) {
191; CHECK-LABEL: @test_ne_0_and_15_add_1(
192; CHECK-NEXT:  entry:
193; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[A:%.*]], 15
194; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[TMP0]], 15
195; CHECK-NEXT:    ret i1 [[CMP]]
196;
197entry:
198  %add = add i8 %a, 1
199  %and = and i8 %add, 15
200  %cmp = icmp ne i8 %and, 0
201  ret i1 %cmp
202}
203
204define i1 @test_eq_0_and_15_add_3(i8 %a) {
205; CHECK-LABEL: @test_eq_0_and_15_add_3(
206; CHECK-NEXT:  entry:
207; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[A:%.*]], 15
208; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[TMP0]], 13
209; CHECK-NEXT:    ret i1 [[CMP]]
210;
211entry:
212  %add = add i8 %a, 3
213  %and = and i8 %add, 15
214  %cmp = icmp eq i8 %and, 0
215  ret i1 %cmp
216}
217
218define i1 @test_ne_0_and_15_add_3(i8 %a) {
219; CHECK-LABEL: @test_ne_0_and_15_add_3(
220; CHECK-NEXT:  entry:
221; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[A:%.*]], 15
222; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[TMP0]], 13
223; CHECK-NEXT:    ret i1 [[CMP]]
224;
225entry:
226  %add = add i8 %a, 3
227  %and = and i8 %add, 15
228  %cmp = icmp ne i8 %and, 0
229  ret i1 %cmp
230}
231
232define i1 @test_eq_11_and_15_add_10(i8 %a) {
233; CHECK-LABEL: @test_eq_11_and_15_add_10(
234; CHECK-NEXT:  entry:
235; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[A:%.*]], 15
236; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[TMP0]], 1
237; CHECK-NEXT:    ret i1 [[CMP]]
238;
239entry:
240  %add = add i8 %a, 10
241  %and = and i8 %add, 15
242  %cmp = icmp eq i8 %and, 11
243  ret i1 %cmp
244}
245
246define i1 @test_ne_11_and_15_add_10(i8 %a) {
247; CHECK-LABEL: @test_ne_11_and_15_add_10(
248; CHECK-NEXT:  entry:
249; CHECK-NEXT:    [[TMP0:%.*]] = and i8 [[A:%.*]], 15
250; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[TMP0]], 1
251; CHECK-NEXT:    ret i1 [[CMP]]
252;
253entry:
254  %add = add i8 %a, 10
255  %and = and i8 %add, 15
256  %cmp = icmp ne i8 %and, 11
257  ret i1 %cmp
258}
259