xref: /llvm-project/llvm/test/Transforms/InstCombine/merge-icmp.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
4declare void @use.i1(i1)
5declare void @use.i8(i8)
6declare void @use.i16(i16)
7
8define i1 @and_test1(ptr %x) {
9; CHECK-LABEL: @and_test1(
10; CHECK-NEXT:    [[LOAD:%.*]] = load i16, ptr [[X:%.*]], align 4
11; CHECK-NEXT:    [[OR:%.*]] = icmp eq i16 [[LOAD]], 17791
12; CHECK-NEXT:    ret i1 [[OR]]
13;
14  %load = load i16, ptr %x, align 4
15  %trunc = trunc i16 %load to i8
16  %cmp1 = icmp eq i8 %trunc, 127
17  %and = and i16 %load, -256
18  %cmp2 = icmp eq i16 %and, 17664
19  %or = and i1 %cmp1, %cmp2
20  ret i1 %or
21}
22
23define i1 @and_test1_logical(ptr %x) {
24; CHECK-LABEL: @and_test1_logical(
25; CHECK-NEXT:    [[LOAD:%.*]] = load i16, ptr [[X:%.*]], align 4
26; CHECK-NEXT:    [[OR:%.*]] = icmp eq i16 [[LOAD]], 17791
27; CHECK-NEXT:    ret i1 [[OR]]
28;
29  %load = load i16, ptr %x, align 4
30  %trunc = trunc i16 %load to i8
31  %cmp1 = icmp eq i8 %trunc, 127
32  %and = and i16 %load, -256
33  %cmp2 = icmp eq i16 %and, 17664
34  %or = select i1 %cmp1, i1 %cmp2, i1 false
35  ret i1 %or
36}
37
38define <2 x i1> @and_test1_vector(ptr %x) {
39; CHECK-LABEL: @and_test1_vector(
40; CHECK-NEXT:    [[LOAD:%.*]] = load <2 x i16>, ptr [[X:%.*]], align 4
41; CHECK-NEXT:    [[OR:%.*]] = icmp eq <2 x i16> [[LOAD]], splat (i16 17791)
42; CHECK-NEXT:    ret <2 x i1> [[OR]]
43;
44  %load = load <2 x i16>, ptr %x, align 4
45  %trunc = trunc <2 x i16> %load to <2 x i8>
46  %cmp1 = icmp eq <2 x i8> %trunc, <i8 127, i8 127>
47  %and = and <2 x i16> %load, <i16 -256, i16 -256>
48  %cmp2 = icmp eq <2 x i16> %and, <i16 17664, i16 17664>
49  %or = and <2 x i1> %cmp1, %cmp2
50  ret <2 x i1> %or
51}
52
53define i1 @and_test2(ptr %x) {
54; CHECK-LABEL: @and_test2(
55; CHECK-NEXT:    [[LOAD:%.*]] = load i16, ptr [[X:%.*]], align 4
56; CHECK-NEXT:    [[OR:%.*]] = icmp eq i16 [[LOAD]], 32581
57; CHECK-NEXT:    ret i1 [[OR]]
58;
59  %load = load i16, ptr %x, align 4
60  %and = and i16 %load, -256
61  %cmp1 = icmp eq i16 %and, 32512
62  %trunc = trunc i16 %load to i8
63  %cmp2 = icmp eq i8 %trunc, 69
64  %or = and i1 %cmp1, %cmp2
65  ret i1 %or
66}
67
68define i1 @and_test2_logical(ptr %x) {
69; CHECK-LABEL: @and_test2_logical(
70; CHECK-NEXT:    [[LOAD:%.*]] = load i16, ptr [[X:%.*]], align 4
71; CHECK-NEXT:    [[OR:%.*]] = icmp eq i16 [[LOAD]], 32581
72; CHECK-NEXT:    ret i1 [[OR]]
73;
74  %load = load i16, ptr %x, align 4
75  %and = and i16 %load, -256
76  %cmp1 = icmp eq i16 %and, 32512
77  %trunc = trunc i16 %load to i8
78  %cmp2 = icmp eq i8 %trunc, 69
79  %or = select i1 %cmp1, i1 %cmp2, i1 false
80  ret i1 %or
81}
82
83define <2 x i1> @and_test2_vector(ptr %x) {
84; CHECK-LABEL: @and_test2_vector(
85; CHECK-NEXT:    [[LOAD:%.*]] = load <2 x i16>, ptr [[X:%.*]], align 4
86; CHECK-NEXT:    [[OR:%.*]] = icmp eq <2 x i16> [[LOAD]], splat (i16 32581)
87; CHECK-NEXT:    ret <2 x i1> [[OR]]
88;
89  %load = load <2 x i16>, ptr %x, align 4
90  %and = and <2 x i16> %load, <i16 -256, i16 -256>
91  %cmp1 = icmp eq <2 x i16> %and, <i16 32512, i16 32512>
92  %trunc = trunc <2 x i16> %load to <2 x i8>
93  %cmp2 = icmp eq <2 x i8> %trunc, <i8 69, i8 69>
94  %or = and <2 x i1> %cmp1, %cmp2
95  ret <2 x i1> %or
96}
97
98define i1 @or_basic(i16 %load) {
99; CHECK-LABEL: @or_basic(
100; CHECK-NEXT:    [[OR:%.*]] = icmp ne i16 [[LOAD:%.*]], 17791
101; CHECK-NEXT:    ret i1 [[OR]]
102;
103  %trunc = trunc i16 %load to i8
104  %cmp1 = icmp ne i8 %trunc, 127
105  %and = and i16 %load, -256
106  %cmp2 = icmp ne i16 %and, 17664
107  %or = or i1 %cmp1, %cmp2
108  ret i1 %or
109}
110
111define i1 @or_basic_commuted(i16 %load) {
112; CHECK-LABEL: @or_basic_commuted(
113; CHECK-NEXT:    [[OR:%.*]] = icmp ne i16 [[LOAD:%.*]], 32581
114; CHECK-NEXT:    ret i1 [[OR]]
115;
116  %and = and i16 %load, -256
117  %cmp1 = icmp ne i16 %and, 32512
118  %trunc = trunc i16 %load to i8
119  %cmp2 = icmp ne i8 %trunc, 69
120  %or = or i1 %cmp1, %cmp2
121  ret i1 %or
122}
123
124define <2 x i1> @or_vector(<2 x i16> %load) {
125; CHECK-LABEL: @or_vector(
126; CHECK-NEXT:    [[OR:%.*]] = icmp ne <2 x i16> [[LOAD:%.*]], splat (i16 17791)
127; CHECK-NEXT:    ret <2 x i1> [[OR]]
128;
129  %trunc = trunc <2 x i16> %load to <2 x i8>
130  %cmp1 = icmp ne <2 x i8> %trunc, <i8 127, i8 127>
131  %and = and <2 x i16> %load, <i16 -256, i16 -256>
132  %cmp2 = icmp ne <2 x i16> %and, <i16 17664, i16 17664>
133  %or = or <2 x i1> %cmp1, %cmp2
134  ret <2 x i1> %or
135}
136
137define i1 @or_nontrivial_mask1(i16 %load) {
138; CHECK-LABEL: @or_nontrivial_mask1(
139; CHECK-NEXT:    [[TMP1:%.*]] = and i16 [[LOAD:%.*]], 4095
140; CHECK-NEXT:    [[OR:%.*]] = icmp ne i16 [[TMP1]], 1407
141; CHECK-NEXT:    ret i1 [[OR]]
142;
143  %trunc = trunc i16 %load to i8
144  %cmp1 = icmp ne i8 %trunc, 127
145  %and = and i16 %load, 3840
146  %cmp2 = icmp ne i16 %and, 1280
147  %or = or i1 %cmp1, %cmp2
148  ret i1 %or
149}
150
151define i1 @or_nontrivial_mask2(i16 %load) {
152; CHECK-LABEL: @or_nontrivial_mask2(
153; CHECK-NEXT:    [[TMP1:%.*]] = and i16 [[LOAD:%.*]], -3841
154; CHECK-NEXT:    [[OR:%.*]] = icmp ne i16 [[TMP1]], 20607
155; CHECK-NEXT:    ret i1 [[OR]]
156;
157  %trunc = trunc i16 %load to i8
158  %cmp1 = icmp ne i8 %trunc, 127
159  %and = and i16 %load, -4096
160  %cmp2 = icmp ne i16 %and, 20480
161  %or = or i1 %cmp1, %cmp2
162  ret i1 %or
163}
164
165define i1 @or_extra_use1(i16 %load) {
166; CHECK-LABEL: @or_extra_use1(
167; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
168; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127
169; CHECK-NEXT:    call void @use.i1(i1 [[CMP1]])
170; CHECK-NEXT:    [[AND:%.*]] = and i16 [[LOAD]], -4096
171; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i16 [[AND]], 20480
172; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
173; CHECK-NEXT:    ret i1 [[OR]]
174;
175  %trunc = trunc i16 %load to i8
176  %cmp1 = icmp ne i8 %trunc, 127
177  call void @use.i1(i1 %cmp1)
178  %and = and i16 %load, -4096
179  %cmp2 = icmp ne i16 %and, 20480
180  %or = or i1 %cmp1, %cmp2
181  ret i1 %or
182}
183
184define i1 @or_extra_use2(i16 %load) {
185; CHECK-LABEL: @or_extra_use2(
186; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
187; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127
188; CHECK-NEXT:    [[AND:%.*]] = and i16 [[LOAD]], -4096
189; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i16 [[AND]], 20480
190; CHECK-NEXT:    call void @use.i1(i1 [[CMP2]])
191; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
192; CHECK-NEXT:    ret i1 [[OR]]
193;
194  %trunc = trunc i16 %load to i8
195  %cmp1 = icmp ne i8 %trunc, 127
196  %and = and i16 %load, -4096
197  %cmp2 = icmp ne i16 %and, 20480
198  call void @use.i1(i1 %cmp2)
199  %or = or i1 %cmp1, %cmp2
200  ret i1 %or
201}
202
203define i1 @or_extra_use3(i16 %load) {
204; CHECK-LABEL: @or_extra_use3(
205; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
206; CHECK-NEXT:    call void @use.i8(i8 [[TRUNC]])
207; CHECK-NEXT:    [[TMP1:%.*]] = and i16 [[LOAD]], -3841
208; CHECK-NEXT:    [[OR:%.*]] = icmp ne i16 [[TMP1]], 20607
209; CHECK-NEXT:    ret i1 [[OR]]
210;
211  %trunc = trunc i16 %load to i8
212  call void @use.i8(i8 %trunc)
213  %cmp1 = icmp ne i8 %trunc, 127
214  %and = and i16 %load, -4096
215  %cmp2 = icmp ne i16 %and, 20480
216  %or = or i1 %cmp1, %cmp2
217  ret i1 %or
218}
219
220define i1 @or_extra_use4(i16 %load) {
221; CHECK-LABEL: @or_extra_use4(
222; CHECK-NEXT:    [[AND:%.*]] = and i16 [[LOAD:%.*]], -4096
223; CHECK-NEXT:    call void @use.i16(i16 [[AND]])
224; CHECK-NEXT:    [[TMP1:%.*]] = and i16 [[LOAD]], -3841
225; CHECK-NEXT:    [[OR:%.*]] = icmp ne i16 [[TMP1]], 20607
226; CHECK-NEXT:    ret i1 [[OR]]
227;
228  %trunc = trunc i16 %load to i8
229  %cmp1 = icmp ne i8 %trunc, 127
230  %and = and i16 %load, -4096
231  call void @use.i16(i16 %and)
232  %cmp2 = icmp ne i16 %and, 20480
233  %or = or i1 %cmp1, %cmp2
234  ret i1 %or
235}
236
237define i1 @or_wrong_pred1(i16 %load) {
238; CHECK-LABEL: @or_wrong_pred1(
239; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
240; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[TRUNC]], 127
241; CHECK-NEXT:    [[AND:%.*]] = and i16 [[LOAD]], -256
242; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i16 [[AND]], 17664
243; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
244; CHECK-NEXT:    ret i1 [[OR]]
245;
246  %trunc = trunc i16 %load to i8
247  %cmp1 = icmp eq i8 %trunc, 127
248  %and = and i16 %load, -256
249  %cmp2 = icmp ne i16 %and, 17664
250  %or = or i1 %cmp1, %cmp2
251  ret i1 %or
252}
253
254define i1 @or_wrong_pred2(i16 %load) {
255; CHECK-LABEL: @or_wrong_pred2(
256; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
257; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127
258; CHECK-NEXT:    [[AND:%.*]] = and i16 [[LOAD]], -256
259; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i16 [[AND]], 17664
260; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
261; CHECK-NEXT:    ret i1 [[OR]]
262;
263  %trunc = trunc i16 %load to i8
264  %cmp1 = icmp ne i8 %trunc, 127
265  %and = and i16 %load, -256
266  %cmp2 = icmp eq i16 %and, 17664
267  %or = or i1 %cmp1, %cmp2
268  ret i1 %or
269}
270
271define i1 @or_wrong_pred3(i16 %load) {
272; CHECK-LABEL: @or_wrong_pred3(
273; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
274; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[TRUNC]], 127
275; CHECK-NEXT:    [[AND:%.*]] = and i16 [[LOAD]], -256
276; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i16 [[AND]], 17664
277; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
278; CHECK-NEXT:    ret i1 [[OR]]
279;
280  %trunc = trunc i16 %load to i8
281  %cmp1 = icmp eq i8 %trunc, 127
282  %and = and i16 %load, -256
283  %cmp2 = icmp eq i16 %and, 17664
284  %or = or i1 %cmp1, %cmp2
285  ret i1 %or
286}
287
288define i1 @or_wrong_op(i16 %load, i16 %other) {
289; CHECK-LABEL: @or_wrong_op(
290; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
291; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127
292; CHECK-NEXT:    [[AND:%.*]] = and i16 [[OTHER:%.*]], -256
293; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i16 [[AND]], 17664
294; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
295; CHECK-NEXT:    ret i1 [[OR]]
296;
297  %trunc = trunc i16 %load to i8
298  %cmp1 = icmp ne i8 %trunc, 127
299  %and = and i16 %other, -256
300  %cmp2 = icmp ne i16 %and, 17664
301  %or = or i1 %cmp1, %cmp2
302  ret i1 %or
303}
304
305define i1 @or_wrong_const1(i16 %load) {
306; CHECK-LABEL: @or_wrong_const1(
307; CHECK-NEXT:    ret i1 true
308;
309  %trunc = trunc i16 %load to i8
310  %cmp1 = icmp ne i8 %trunc, 127
311  %and = and i16 %load, -256
312  %cmp2 = icmp ne i16 %and, 17665
313  %or = or i1 %cmp1, %cmp2
314  ret i1 %or
315}
316
317define i1 @or_wrong_const2(i16 %load) {
318; CHECK-LABEL: @or_wrong_const2(
319; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i16 [[LOAD:%.*]] to i8
320; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i8 [[TRUNC]], 127
321; CHECK-NEXT:    [[AND:%.*]] = and i16 [[LOAD]], -255
322; CHECK-NEXT:    [[CMP2:%.*]] = icmp ne i16 [[AND]], 17665
323; CHECK-NEXT:    [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]]
324; CHECK-NEXT:    ret i1 [[OR]]
325;
326  %trunc = trunc i16 %load to i8
327  %cmp1 = icmp ne i8 %trunc, 127
328  %and = and i16 %load, -255
329  %cmp2 = icmp ne i16 %and, 17665
330  %or = or i1 %cmp1, %cmp2
331  ret i1 %or
332}
333