xref: /llvm-project/llvm/test/Transforms/InstCombine/icmp-of-or-x.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 @llvm.assume(i1)
5declare void @barrier()
6declare void @use.v2i8(<2 x i8>)
7declare void @use.i8(i8)
8
9define i1 @or_ugt(i8 %x, i8 %y) {
10; CHECK-LABEL: @or_ugt(
11; CHECK-NEXT:    [[XN1:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
12; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[XN1]], [[X]]
13; CHECK-NEXT:    ret i1 [[R]]
14;
15  %xn1 = or i8 %x, %y
16  %r = icmp ugt i8 %xn1, %x
17  ret i1 %r
18}
19
20define <2 x i1> @or_ule(<2 x i8> %x, <2 x i8> %y) {
21; CHECK-LABEL: @or_ule(
22; CHECK-NEXT:    [[XN1:%.*]] = or <2 x i8> [[X:%.*]], [[Y:%.*]]
23; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[XN1]], [[X]]
24; CHECK-NEXT:    ret <2 x i1> [[R]]
25;
26  %xn1 = or <2 x i8> %x, %y
27  %r = icmp ule <2 x i8> %xn1, %x
28  ret <2 x i1> %r
29}
30
31define <2 x i1> @or_slt_pos(<2 x i8> %xx, <2 x i8> %yy, <2 x i8> %z) {
32; CHECK-LABEL: @or_slt_pos(
33; CHECK-NEXT:    [[X:%.*]] = add <2 x i8> [[XX:%.*]], [[Z:%.*]]
34; CHECK-NEXT:    [[Y:%.*]] = and <2 x i8> [[YY:%.*]], splat (i8 127)
35; CHECK-NEXT:    [[XN1:%.*]] = or <2 x i8> [[X]], [[Y]]
36; CHECK-NEXT:    [[R:%.*]] = icmp slt <2 x i8> [[X]], [[XN1]]
37; CHECK-NEXT:    ret <2 x i1> [[R]]
38;
39  %x = add <2 x i8> %xx, %z
40  %y = and <2 x i8> %yy, <i8 127, i8 127>
41  %xn1 = or <2 x i8> %x, %y
42  %r = icmp slt <2 x i8> %x, %xn1
43  ret <2 x i1> %r
44}
45
46define i1 @or_sle_pos(i8 %x, i8 %y) {
47; CHECK-LABEL: @or_sle_pos(
48; CHECK-NEXT:    [[NS:%.*]] = icmp sgt i8 [[Y:%.*]], -1
49; CHECK-NEXT:    call void @llvm.assume(i1 [[NS]])
50; CHECK-NEXT:    [[XN1:%.*]] = or i8 [[X:%.*]], [[Y]]
51; CHECK-NEXT:    [[R:%.*]] = icmp sle i8 [[XN1]], [[X]]
52; CHECK-NEXT:    ret i1 [[R]]
53;
54  %ns = icmp sge i8 %y, 0
55  call void @llvm.assume(i1 %ns)
56  %xn1 = or i8 %x, %y
57  %r = icmp sle i8 %xn1, %x
58  ret i1 %r
59}
60
61define i1 @or_sle_fail_maybe_neg(i8 %x, i8 %y) {
62; CHECK-LABEL: @or_sle_fail_maybe_neg(
63; CHECK-NEXT:    [[XN1:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
64; CHECK-NEXT:    [[R:%.*]] = icmp sle i8 [[XN1]], [[X]]
65; CHECK-NEXT:    ret i1 [[R]]
66;
67  %xn1 = or i8 %x, %y
68  %r = icmp sle i8 %xn1, %x
69  ret i1 %r
70}
71
72define i1 @or_eq_noundef(i8 %x, i8 noundef %y) {
73; CHECK-LABEL: @or_eq_noundef(
74; CHECK-NEXT:    [[XN1:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
75; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[XN1]], [[X]]
76; CHECK-NEXT:    ret i1 [[R]]
77;
78  %xn1 = or i8 %x, %y
79  %r = icmp eq i8 %xn1, %x
80  ret i1 %r
81}
82
83define i1 @or_eq_notY_eq_0(i8 %x, i8 %y) {
84; CHECK-LABEL: @or_eq_notY_eq_0(
85; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
86; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
87; CHECK-NEXT:    ret i1 [[CMP]]
88;
89  %ny = xor i8 %y, -1
90  %or = or i8 %x, %ny
91  %cmp = icmp eq i8 %or, %ny
92  ret i1 %cmp
93}
94
95define i1 @or_eq_notY_eq_0_fail_multiuse(i8 %x, i8 %y) {
96; CHECK-LABEL: @or_eq_notY_eq_0_fail_multiuse(
97; CHECK-NEXT:    [[NY:%.*]] = xor i8 [[Y:%.*]], -1
98; CHECK-NEXT:    [[OR:%.*]] = or i8 [[X:%.*]], [[NY]]
99; CHECK-NEXT:    call void @use.i8(i8 [[OR]])
100; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[OR]], [[NY]]
101; CHECK-NEXT:    ret i1 [[CMP]]
102;
103  %ny = xor i8 %y, -1
104  %or = or i8 %x, %ny
105  call void @use.i8(i8 %or)
106  %cmp = icmp eq i8 %or, %ny
107  ret i1 %cmp
108}
109
110define i1 @or_ne_notY_eq_1s(i8 %x, i8 %y) {
111; CHECK-LABEL: @or_ne_notY_eq_1s(
112; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
113; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[TMP1]], -1
114; CHECK-NEXT:    ret i1 [[CMP]]
115;
116  %ny = xor i8 %y, -1
117  %or = or i8 %x, %ny
118  %cmp = icmp ne i8 %or, %x
119  ret i1 %cmp
120}
121
122define i1 @or_ne_notY_eq_1s_fail_bad_not(i8 %x, i8 %y) {
123; CHECK-LABEL: @or_ne_notY_eq_1s_fail_bad_not(
124; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[Y:%.*]], 1
125; CHECK-NEXT:    [[TMP2:%.*]] = or i8 [[X:%.*]], [[TMP1]]
126; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[TMP2]], -1
127; CHECK-NEXT:    ret i1 [[CMP]]
128;
129  %ny = xor i8 %y, -2
130  %or = or i8 %x, %ny
131  %cmp = icmp ne i8 %or, %x
132  ret i1 %cmp
133}
134
135define <2 x i1> @or_ne_vecC(<2 x i8> %x) {
136; CHECK-LABEL: @or_ne_vecC(
137; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 -10, i8 -43>
138; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i8> [[TMP1]], zeroinitializer
139; CHECK-NEXT:    ret <2 x i1> [[CMP]]
140;
141  %or = or <2 x i8> %x, <i8 9, i8 42>
142  %cmp = icmp ne <2 x i8> %or, <i8 9, i8 42>
143  ret <2 x i1> %cmp
144}
145
146define i1 @or_eq_fail_maybe_undef(i8 %x, i8 %y) {
147; CHECK-LABEL: @or_eq_fail_maybe_undef(
148; CHECK-NEXT:    [[XN1:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
149; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[XN1]], [[X]]
150; CHECK-NEXT:    ret i1 [[R]]
151;
152  %xn1 = or i8 %x, %y
153  %r = icmp eq i8 %xn1, %x
154  ret i1 %r
155}
156
157define <2 x i1> @or_ne_noundef(<2 x i8> %x, <2 x i8> noundef %y) {
158; CHECK-LABEL: @or_ne_noundef(
159; CHECK-NEXT:    [[XN1:%.*]] = or <2 x i8> [[X:%.*]], [[Y:%.*]]
160; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i8> [[XN1]], [[X]]
161; CHECK-NEXT:    ret <2 x i1> [[R]]
162;
163  %xn1 = or <2 x i8> %x, %y
164  %r = icmp ne <2 x i8> %xn1, %x
165  ret <2 x i1> %r
166}
167
168define <2 x i1> @or_ne_noundef_fail_reuse(<2 x i8> %x, <2 x i8> noundef %y) {
169; CHECK-LABEL: @or_ne_noundef_fail_reuse(
170; CHECK-NEXT:    [[XN1:%.*]] = or <2 x i8> [[X:%.*]], [[Y:%.*]]
171; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i8> [[XN1]], [[X]]
172; CHECK-NEXT:    call void @use.v2i8(<2 x i8> [[XN1]])
173; CHECK-NEXT:    ret <2 x i1> [[R]]
174;
175  %xn1 = or <2 x i8> %x, %y
176  %r = icmp ne <2 x i8> %xn1, %x
177  call void @use.v2i8(<2 x i8> %xn1)
178  ret <2 x i1> %r
179}
180
181define i1 @or_slt_intmin(i8 %x) {
182; CHECK-LABEL: @or_slt_intmin(
183; CHECK-NEXT:    [[XN1:%.*]] = or i8 [[X:%.*]], -128
184; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[XN1]], [[X]]
185; CHECK-NEXT:    ret i1 [[R]]
186;
187  %xn1 = or i8 %x, 128
188  %r = icmp slt i8 %xn1, %x
189  ret i1 %r
190}
191
192define <2 x i1> @or_slt_intmin_2(<2 x i8> %xx, <2 x i8> %z) {
193; CHECK-LABEL: @or_slt_intmin_2(
194; CHECK-NEXT:    [[X:%.*]] = add <2 x i8> [[XX:%.*]], [[Z:%.*]]
195; CHECK-NEXT:    [[XN1:%.*]] = or <2 x i8> [[X]], splat (i8 -128)
196; CHECK-NEXT:    [[R:%.*]] = icmp slt <2 x i8> [[X]], [[XN1]]
197; CHECK-NEXT:    ret <2 x i1> [[R]]
198;
199  %x = add <2 x i8> %xx, %z
200  %xn1 = or <2 x i8> %x, <i8 128, i8 128>
201  %r = icmp slt <2 x i8> %x, %xn1
202  ret <2 x i1> %r
203}
204
205define i1 @or_sle_intmin_indirect_2(i8 %xx, i8 %C, i8 %z) {
206; CHECK-LABEL: @or_sle_intmin_indirect_2(
207; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[C:%.*]], -128
208; CHECK-NEXT:    br i1 [[CMP]], label [[NEG:%.*]], label [[POS:%.*]]
209; CHECK:       neg:
210; CHECK-NEXT:    [[X:%.*]] = add i8 [[XX:%.*]], [[Z:%.*]]
211; CHECK-NEXT:    [[XN1:%.*]] = or i8 [[X]], -128
212; CHECK-NEXT:    [[R:%.*]] = icmp sle i8 [[X]], [[XN1]]
213; CHECK-NEXT:    ret i1 [[R]]
214; CHECK:       pos:
215; CHECK-NEXT:    call void @barrier()
216; CHECK-NEXT:    ret i1 false
217;
218  %x = add i8 %xx, %z
219  %NC = sub i8 0, %C
220  %CP2 = and i8 %C, %NC
221  %cmp = icmp slt i8 %CP2, 0
222  br i1 %cmp, label %neg, label %pos
223neg:
224  %xn1 = or i8 %x, %CP2
225  %r = icmp sle i8 %x, %xn1
226  ret i1 %r
227pos:
228  call void @barrier()
229  ret i1 0
230}
231
232define i1 @or_sge_intmin(i8 %x) {
233; CHECK-LABEL: @or_sge_intmin(
234; CHECK-NEXT:    [[XN1:%.*]] = or i8 [[X:%.*]], -128
235; CHECK-NEXT:    [[R:%.*]] = icmp sge i8 [[XN1]], [[X]]
236; CHECK-NEXT:    ret i1 [[R]]
237;
238  %xn1 = or i8 %x, 128
239  %r = icmp sge i8 %xn1, %x
240  ret i1 %r
241}
242
243define i1 @or_sgt_intmin_indirect(i8 %x, i8 %C) {
244; CHECK-LABEL: @or_sgt_intmin_indirect(
245; CHECK-NEXT:    [[C_NOT:%.*]] = icmp eq i8 [[C:%.*]], -128
246; CHECK-NEXT:    br i1 [[C_NOT]], label [[NEG:%.*]], label [[POS:%.*]]
247; CHECK:       neg:
248; CHECK-NEXT:    [[XN1:%.*]] = or i8 [[X:%.*]], -128
249; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[XN1]], [[X]]
250; CHECK-NEXT:    ret i1 [[R]]
251; CHECK:       pos:
252; CHECK-NEXT:    call void @barrier()
253; CHECK-NEXT:    ret i1 false
254;
255  %NC = sub i8 0, %C
256  %CP2 = and i8 %C, %NC
257  %c = icmp sge i8 %CP2, 0
258  br i1 %c, label %pos, label %neg
259neg:
260  %xn1 = or i8 %x, %CP2
261  %r = icmp sgt i8 %xn1, %x
262  ret i1 %r
263pos:
264  call void @barrier()
265  ret i1 0
266}
267
268define <2 x i1> @or_sgt_intmin_2(<2 x i8> %xx, <2 x i8> %z) {
269; CHECK-LABEL: @or_sgt_intmin_2(
270; CHECK-NEXT:    [[X:%.*]] = add <2 x i8> [[XX:%.*]], [[Z:%.*]]
271; CHECK-NEXT:    [[XN1:%.*]] = or <2 x i8> [[X]], splat (i8 -128)
272; CHECK-NEXT:    [[R:%.*]] = icmp sgt <2 x i8> [[X]], [[XN1]]
273; CHECK-NEXT:    ret <2 x i1> [[R]]
274;
275  %x = add <2 x i8> %xx, %z
276  %xn1 = or <2 x i8> %x, <i8 128, i8 128>
277  %r = icmp sgt <2 x i8> %x, %xn1
278  ret <2 x i1> %r
279}
280
281define i1 @or_simplify_ule(i8 %y_in, i8 %rhs_in, i1 %c) {
282; CHECK-LABEL: @or_simplify_ule(
283; CHECK-NEXT:    [[RHS:%.*]] = and i8 [[RHS_IN:%.*]], -2
284; CHECK-NEXT:    [[Y:%.*]] = or i8 [[Y_IN:%.*]], [[RHS_IN]]
285; CHECK-NEXT:    [[LBO:%.*]] = or i8 [[Y]], 1
286; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[LBO]], [[RHS]]
287; CHECK-NEXT:    ret i1 [[R]]
288;
289  %y = or i8 %y_in, 1
290  %rhs = and i8 %rhs_in, -2
291  %lbo = or i8 %y, %rhs
292  %r = icmp ule i8 %lbo, %rhs
293  ret i1 %r
294}
295
296define i1 @or_simplify_uge(i8 %y_in, i8 %rhs_in, i1 %c) {
297; CHECK-LABEL: @or_simplify_uge(
298; CHECK-NEXT:    ret i1 false
299;
300  %y = or i8 %y_in, 129
301  %rhs = and i8 %rhs_in, 127
302  %lbo = or i8 %y, %rhs
303  %r = icmp uge i8 %rhs, %lbo
304  ret i1 %r
305}
306
307define i1 @or_simplify_ule_fail(i8 %y_in, i8 %rhs_in) {
308; CHECK-LABEL: @or_simplify_ule_fail(
309; CHECK-NEXT:    [[RHS:%.*]] = and i8 [[RHS_IN:%.*]], 127
310; CHECK-NEXT:    [[Y:%.*]] = or i8 [[Y_IN:%.*]], [[RHS]]
311; CHECK-NEXT:    [[LBO:%.*]] = or i8 [[Y]], 64
312; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[LBO]], [[RHS]]
313; CHECK-NEXT:    ret i1 [[R]]
314;
315  %y = or i8 %y_in, 64
316  %rhs = and i8 %rhs_in, 127
317  %lbo = or i8 %y, %rhs
318  %r = icmp ule i8 %lbo, %rhs
319  ret i1 %r
320}
321
322define i1 @or_simplify_ugt(i8 %y_in, i8 %rhs_in) {
323; CHECK-LABEL: @or_simplify_ugt(
324; CHECK-NEXT:    [[RHS:%.*]] = and i8 [[RHS_IN:%.*]], -2
325; CHECK-NEXT:    [[Y:%.*]] = or i8 [[Y_IN:%.*]], [[RHS_IN]]
326; CHECK-NEXT:    [[LBO:%.*]] = or i8 [[Y]], 1
327; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[LBO]], [[RHS]]
328; CHECK-NEXT:    ret i1 [[R]]
329;
330  %y = or i8 %y_in, 1
331  %rhs = and i8 %rhs_in, -2
332  %lbo = or i8 %y, %rhs
333  %r = icmp ugt i8 %lbo, %rhs
334  ret i1 %r
335}
336
337define i1 @or_simplify_ult(i8 %y_in, i8 %rhs_in) {
338; CHECK-LABEL: @or_simplify_ult(
339; CHECK-NEXT:    [[RHS:%.*]] = and i8 [[RHS_IN:%.*]], -5
340; CHECK-NEXT:    [[Y:%.*]] = or i8 [[Y_IN:%.*]], [[RHS_IN]]
341; CHECK-NEXT:    [[LBO:%.*]] = or i8 [[Y]], 36
342; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[RHS]], [[LBO]]
343; CHECK-NEXT:    ret i1 [[R]]
344;
345  %y = or i8 %y_in, 36
346  %rhs = and i8 %rhs_in, -5
347  %lbo = or i8 %y, %rhs
348  %r = icmp ult i8 %rhs, %lbo
349  ret i1 %r
350}
351
352define i1 @or_simplify_ugt_fail(i8 %y_in, i8 %rhs_in) {
353; CHECK-LABEL: @or_simplify_ugt_fail(
354; CHECK-NEXT:    [[RHS:%.*]] = or i8 [[RHS_IN:%.*]], 1
355; CHECK-NEXT:    [[LBO:%.*]] = or i8 [[Y_IN:%.*]], [[RHS]]
356; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[LBO]], [[RHS]]
357; CHECK-NEXT:    ret i1 [[R]]
358;
359  %y = and i8 %y_in, -2
360  %rhs = or i8 %rhs_in, 1
361  %lbo = or i8 %y, %rhs
362  %r = icmp ugt i8 %lbo, %rhs
363  ret i1 %r
364}
365
366define i1 @pr64610(ptr %b) {
367; CHECK-LABEL: @pr64610(
368; CHECK-NEXT:    ret i1 true
369;
370  %v = load i1, ptr %b, align 2
371  %s = select i1 %v, i32 74, i32 0
372  %or = or i32 %s, 1
373  %r = icmp ugt i32 %or, %s
374  ret i1 %r
375}
376
377define i1 @icmp_eq_x_invertable_y2_todo(i8 %x, i1 %y, i8 %z) {
378; CHECK-LABEL: @icmp_eq_x_invertable_y2_todo(
379; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[Y:%.*]], i8 -8, i8 [[Z:%.*]]
380; CHECK-NEXT:    [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]]
381; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[TMP2]], 0
382; CHECK-NEXT:    ret i1 [[R]]
383;
384  %zz = xor i8 %z, -1
385  %yy = select i1 %y, i8 7, i8 %zz
386  %or = or i8 %x, %yy
387  %r = icmp eq i8 %yy, %or
388  ret i1 %r
389}
390
391define i1 @icmp_eq_x_invertable_y2(i8 %x, i8 %y) {
392; CHECK-LABEL: @icmp_eq_x_invertable_y2(
393; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
394; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[TMP1]], 0
395; CHECK-NEXT:    ret i1 [[R]]
396;
397  %yy = xor i8 %y, -1
398  %or = or i8 %x, %yy
399  %r = icmp eq i8 %yy, %or
400  ret i1 %r
401}
402
403define i1 @PR38139(i8 %arg) {
404; CHECK-LABEL: @PR38139(
405; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[ARG:%.*]], -64
406; CHECK-NEXT:    ret i1 [[R]]
407;
408  %masked = or i8 %arg, 192
409  %r = icmp ne i8 %masked, %arg
410  ret i1 %r
411}
412