Skip to content

Commit bce55fb

Browse files
committed
[InstCombine] Add tests for transforming (icmp (or X, Y), X); NFC
Differential Revision: https://reviews.llvm.org/D144609
1 parent e7f7b63 commit bce55fb

File tree

1 file changed

+385
-0
lines changed

1 file changed

+385
-0
lines changed
Lines changed: 385 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,385 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3+
4+
declare void @llvm.assume(i1)
5+
declare void @barrier()
6+
declare void @use.v2i8(<2 x i8>)
7+
declare void @use.i8(i8)
8+
9+
define 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 ugt 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+
20+
define <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 ule <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+
31+
define <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:%.*]], <i8 127, 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+
46+
define 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+
61+
define 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+
72+
define 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+
83+
define i1 @or_eq_notY_eq_0(i8 %x, i8 %y) {
84+
; CHECK-LABEL: @or_eq_notY_eq_0(
85+
; CHECK-NEXT: [[NY:%.*]] = xor i8 [[Y:%.*]], -1
86+
; CHECK-NEXT: [[OR:%.*]] = or i8 [[NY]], [[X:%.*]]
87+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[OR]], [[NY]]
88+
; CHECK-NEXT: ret i1 [[CMP]]
89+
;
90+
%ny = xor i8 %y, -1
91+
%or = or i8 %x, %ny
92+
%cmp = icmp eq i8 %or, %ny
93+
ret i1 %cmp
94+
}
95+
96+
define i1 @or_eq_notY_eq_0_fail_multiuse(i8 %x, i8 %y) {
97+
; CHECK-LABEL: @or_eq_notY_eq_0_fail_multiuse(
98+
; CHECK-NEXT: [[NY:%.*]] = xor i8 [[Y:%.*]], -1
99+
; CHECK-NEXT: [[OR:%.*]] = or i8 [[NY]], [[X:%.*]]
100+
; CHECK-NEXT: call void @use.i8(i8 [[OR]])
101+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[OR]], [[NY]]
102+
; CHECK-NEXT: ret i1 [[CMP]]
103+
;
104+
%ny = xor i8 %y, -1
105+
%or = or i8 %x, %ny
106+
call void @use.i8(i8 %or)
107+
%cmp = icmp eq i8 %or, %ny
108+
ret i1 %cmp
109+
}
110+
111+
define i1 @or_ne_notY_eq_1s(i8 %x, i8 %y) {
112+
; CHECK-LABEL: @or_ne_notY_eq_1s(
113+
; CHECK-NEXT: [[NY:%.*]] = xor i8 [[Y:%.*]], -1
114+
; CHECK-NEXT: [[OR:%.*]] = or i8 [[NY]], [[X:%.*]]
115+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[OR]], [[X]]
116+
; CHECK-NEXT: ret i1 [[CMP]]
117+
;
118+
%ny = xor i8 %y, -1
119+
%or = or i8 %x, %ny
120+
%cmp = icmp ne i8 %or, %x
121+
ret i1 %cmp
122+
}
123+
124+
define i1 @or_ne_notY_eq_1s_fail_bad_not(i8 %x, i8 %y) {
125+
; CHECK-LABEL: @or_ne_notY_eq_1s_fail_bad_not(
126+
; CHECK-NEXT: [[NY:%.*]] = xor i8 [[Y:%.*]], -2
127+
; CHECK-NEXT: [[OR:%.*]] = or i8 [[NY]], [[X:%.*]]
128+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[OR]], [[X]]
129+
; CHECK-NEXT: ret i1 [[CMP]]
130+
;
131+
%ny = xor i8 %y, -2
132+
%or = or i8 %x, %ny
133+
%cmp = icmp ne i8 %or, %x
134+
ret i1 %cmp
135+
}
136+
137+
define <2 x i1> @or_ne_vecC(<2 x i8> %x) {
138+
; CHECK-LABEL: @or_ne_vecC(
139+
; CHECK-NEXT: [[OR:%.*]] = or <2 x i8> [[X:%.*]], <i8 9, i8 42>
140+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne <2 x i8> [[OR]], <i8 9, i8 42>
141+
; CHECK-NEXT: ret <2 x i1> [[CMP]]
142+
;
143+
%or = or <2 x i8> %x, <i8 9, i8 42>
144+
%cmp = icmp ne <2 x i8> %or, <i8 9, i8 42>
145+
ret <2 x i1> %cmp
146+
}
147+
148+
define i1 @or_eq_fail_maybe_undef(i8 %x, i8 %y) {
149+
; CHECK-LABEL: @or_eq_fail_maybe_undef(
150+
; CHECK-NEXT: [[XN1:%.*]] = or i8 [[X:%.*]], [[Y:%.*]]
151+
; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[XN1]], [[X]]
152+
; CHECK-NEXT: ret i1 [[R]]
153+
;
154+
%xn1 = or i8 %x, %y
155+
%r = icmp eq i8 %xn1, %x
156+
ret i1 %r
157+
}
158+
159+
define <2 x i1> @or_ne_noundef(<2 x i8> %x, <2 x i8> noundef %y) {
160+
; CHECK-LABEL: @or_ne_noundef(
161+
; CHECK-NEXT: [[XN1:%.*]] = or <2 x i8> [[X:%.*]], [[Y:%.*]]
162+
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[XN1]], [[X]]
163+
; CHECK-NEXT: ret <2 x i1> [[R]]
164+
;
165+
%xn1 = or <2 x i8> %x, %y
166+
%r = icmp ne <2 x i8> %xn1, %x
167+
ret <2 x i1> %r
168+
}
169+
170+
define <2 x i1> @or_ne_noundef_fail_reuse(<2 x i8> %x, <2 x i8> noundef %y) {
171+
; CHECK-LABEL: @or_ne_noundef_fail_reuse(
172+
; CHECK-NEXT: [[XN1:%.*]] = or <2 x i8> [[X:%.*]], [[Y:%.*]]
173+
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[XN1]], [[X]]
174+
; CHECK-NEXT: call void @use.v2i8(<2 x i8> [[XN1]])
175+
; CHECK-NEXT: ret <2 x i1> [[R]]
176+
;
177+
%xn1 = or <2 x i8> %x, %y
178+
%r = icmp ne <2 x i8> %xn1, %x
179+
call void @use.v2i8(<2 x i8> %xn1)
180+
ret <2 x i1> %r
181+
}
182+
183+
define i1 @or_slt_intmin(i8 %x) {
184+
; CHECK-LABEL: @or_slt_intmin(
185+
; CHECK-NEXT: [[XN1:%.*]] = or i8 [[X:%.*]], -128
186+
; CHECK-NEXT: [[R:%.*]] = icmp slt i8 [[XN1]], [[X]]
187+
; CHECK-NEXT: ret i1 [[R]]
188+
;
189+
%xn1 = or i8 %x, 128
190+
%r = icmp slt i8 %xn1, %x
191+
ret i1 %r
192+
}
193+
194+
define <2 x i1> @or_slt_intmin_2(<2 x i8> %xx, <2 x i8> %z) {
195+
; CHECK-LABEL: @or_slt_intmin_2(
196+
; CHECK-NEXT: [[X:%.*]] = add <2 x i8> [[XX:%.*]], [[Z:%.*]]
197+
; CHECK-NEXT: [[XN1:%.*]] = or <2 x i8> [[X]], <i8 -128, i8 -128>
198+
; CHECK-NEXT: [[R:%.*]] = icmp slt <2 x i8> [[X]], [[XN1]]
199+
; CHECK-NEXT: ret <2 x i1> [[R]]
200+
;
201+
%x = add <2 x i8> %xx, %z
202+
%xn1 = or <2 x i8> %x, <i8 128, i8 128>
203+
%r = icmp slt <2 x i8> %x, %xn1
204+
ret <2 x i1> %r
205+
}
206+
207+
define i1 @or_sle_intmin_indirect_2(i8 %xx, i8 %C, i8 %z) {
208+
; CHECK-LABEL: @or_sle_intmin_indirect_2(
209+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C:%.*]], -128
210+
; CHECK-NEXT: br i1 [[CMP]], label [[NEG:%.*]], label [[POS:%.*]]
211+
; CHECK: neg:
212+
; CHECK-NEXT: [[NC:%.*]] = sub i8 0, [[C]]
213+
; CHECK-NEXT: [[CP2:%.*]] = and i8 [[NC]], [[C]]
214+
; CHECK-NEXT: [[X:%.*]] = add i8 [[XX:%.*]], [[Z:%.*]]
215+
; CHECK-NEXT: [[XN1:%.*]] = or i8 [[X]], [[CP2]]
216+
; CHECK-NEXT: [[R:%.*]] = icmp sle i8 [[X]], [[XN1]]
217+
; CHECK-NEXT: ret i1 [[R]]
218+
; CHECK: pos:
219+
; CHECK-NEXT: call void @barrier()
220+
; CHECK-NEXT: ret i1 false
221+
;
222+
%x = add i8 %xx, %z
223+
%NC = sub i8 0, %C
224+
%CP2 = and i8 %C, %NC
225+
%cmp = icmp slt i8 %CP2, 0
226+
br i1 %cmp, label %neg, label %pos
227+
neg:
228+
%xn1 = or i8 %x, %CP2
229+
%r = icmp sle i8 %x, %xn1
230+
ret i1 %r
231+
pos:
232+
call void @barrier()
233+
ret i1 0
234+
}
235+
236+
define i1 @or_sge_intmin(i8 %x) {
237+
; CHECK-LABEL: @or_sge_intmin(
238+
; CHECK-NEXT: [[XN1:%.*]] = or i8 [[X:%.*]], -128
239+
; CHECK-NEXT: [[R:%.*]] = icmp sge i8 [[XN1]], [[X]]
240+
; CHECK-NEXT: ret i1 [[R]]
241+
;
242+
%xn1 = or i8 %x, 128
243+
%r = icmp sge i8 %xn1, %x
244+
ret i1 %r
245+
}
246+
247+
define i1 @or_sgt_intmin_indirect(i8 %x, i8 %C) {
248+
; CHECK-LABEL: @or_sgt_intmin_indirect(
249+
; CHECK-NEXT: [[C_NOT:%.*]] = icmp eq i8 [[C:%.*]], -128
250+
; CHECK-NEXT: br i1 [[C_NOT]], label [[NEG:%.*]], label [[POS:%.*]]
251+
; CHECK: neg:
252+
; CHECK-NEXT: [[NC:%.*]] = sub i8 0, [[C]]
253+
; CHECK-NEXT: [[CP2:%.*]] = and i8 [[NC]], [[C]]
254+
; CHECK-NEXT: [[XN1:%.*]] = or i8 [[CP2]], [[X:%.*]]
255+
; CHECK-NEXT: [[R:%.*]] = icmp sgt i8 [[XN1]], [[X]]
256+
; CHECK-NEXT: ret i1 [[R]]
257+
; CHECK: pos:
258+
; CHECK-NEXT: call void @barrier()
259+
; CHECK-NEXT: ret i1 false
260+
;
261+
%NC = sub i8 0, %C
262+
%CP2 = and i8 %C, %NC
263+
%c = icmp sge i8 %CP2, 0
264+
br i1 %c, label %pos, label %neg
265+
neg:
266+
%xn1 = or i8 %x, %CP2
267+
%r = icmp sgt i8 %xn1, %x
268+
ret i1 %r
269+
pos:
270+
call void @barrier()
271+
ret i1 0
272+
}
273+
274+
define <2 x i1> @or_sgt_intmin_2(<2 x i8> %xx, <2 x i8> %z) {
275+
; CHECK-LABEL: @or_sgt_intmin_2(
276+
; CHECK-NEXT: [[X:%.*]] = add <2 x i8> [[XX:%.*]], [[Z:%.*]]
277+
; CHECK-NEXT: [[XN1:%.*]] = or <2 x i8> [[X]], <i8 -128, i8 -128>
278+
; CHECK-NEXT: [[R:%.*]] = icmp sgt <2 x i8> [[X]], [[XN1]]
279+
; CHECK-NEXT: ret <2 x i1> [[R]]
280+
;
281+
%x = add <2 x i8> %xx, %z
282+
%xn1 = or <2 x i8> %x, <i8 128, i8 128>
283+
%r = icmp sgt <2 x i8> %x, %xn1
284+
ret <2 x i1> %r
285+
}
286+
287+
define i1 @or_simplify_ule(i8 %y_in, i8 %rhs_in, i1 %c) {
288+
; CHECK-LABEL: @or_simplify_ule(
289+
; CHECK-NEXT: [[RHS:%.*]] = and i8 [[RHS_IN:%.*]], -2
290+
; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], [[RHS_IN]]
291+
; CHECK-NEXT: [[LBO:%.*]] = or i8 [[Y]], 1
292+
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[LBO]], [[RHS]]
293+
; CHECK-NEXT: ret i1 [[R]]
294+
;
295+
%y = or i8 %y_in, 1
296+
%rhs = and i8 %rhs_in, -2
297+
%lbo = or i8 %y, %rhs
298+
%r = icmp ule i8 %lbo, %rhs
299+
ret i1 %r
300+
}
301+
302+
define i1 @or_simplify_uge(i8 %y_in, i8 %rhs_in, i1 %c) {
303+
; CHECK-LABEL: @or_simplify_uge(
304+
; CHECK-NEXT: ret i1 false
305+
;
306+
%y = or i8 %y_in, 129
307+
%rhs = and i8 %rhs_in, 127
308+
%lbo = or i8 %y, %rhs
309+
%r = icmp uge i8 %rhs, %lbo
310+
ret i1 %r
311+
}
312+
313+
define i1 @or_simplify_ule_fail(i8 %y_in, i8 %rhs_in) {
314+
; CHECK-LABEL: @or_simplify_ule_fail(
315+
; CHECK-NEXT: [[RHS:%.*]] = and i8 [[RHS_IN:%.*]], 127
316+
; CHECK-NEXT: [[Y:%.*]] = or i8 [[RHS]], [[Y_IN:%.*]]
317+
; CHECK-NEXT: [[LBO:%.*]] = or i8 [[Y]], 64
318+
; CHECK-NEXT: [[R:%.*]] = icmp ule i8 [[LBO]], [[RHS]]
319+
; CHECK-NEXT: ret i1 [[R]]
320+
;
321+
%y = or i8 %y_in, 64
322+
%rhs = and i8 %rhs_in, 127
323+
%lbo = or i8 %y, %rhs
324+
%r = icmp ule i8 %lbo, %rhs
325+
ret i1 %r
326+
}
327+
328+
define i1 @or_simplify_ugt(i8 %y_in, i8 %rhs_in) {
329+
; CHECK-LABEL: @or_simplify_ugt(
330+
; CHECK-NEXT: [[RHS:%.*]] = and i8 [[RHS_IN:%.*]], -2
331+
; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], [[RHS_IN]]
332+
; CHECK-NEXT: [[LBO:%.*]] = or i8 [[Y]], 1
333+
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[LBO]], [[RHS]]
334+
; CHECK-NEXT: ret i1 [[R]]
335+
;
336+
%y = or i8 %y_in, 1
337+
%rhs = and i8 %rhs_in, -2
338+
%lbo = or i8 %y, %rhs
339+
%r = icmp ugt i8 %lbo, %rhs
340+
ret i1 %r
341+
}
342+
343+
define i1 @or_simplify_ult(i8 %y_in, i8 %rhs_in) {
344+
; CHECK-LABEL: @or_simplify_ult(
345+
; CHECK-NEXT: [[RHS:%.*]] = and i8 [[RHS_IN:%.*]], -5
346+
; CHECK-NEXT: [[Y:%.*]] = or i8 [[Y_IN:%.*]], [[RHS_IN]]
347+
; CHECK-NEXT: [[LBO:%.*]] = or i8 [[Y]], 36
348+
; CHECK-NEXT: [[R:%.*]] = icmp ult i8 [[RHS]], [[LBO]]
349+
; CHECK-NEXT: ret i1 [[R]]
350+
;
351+
%y = or i8 %y_in, 36
352+
%rhs = and i8 %rhs_in, -5
353+
%lbo = or i8 %y, %rhs
354+
%r = icmp ult i8 %rhs, %lbo
355+
ret i1 %r
356+
}
357+
358+
define i1 @or_simplify_ugt_fail(i8 %y_in, i8 %rhs_in) {
359+
; CHECK-LABEL: @or_simplify_ugt_fail(
360+
; CHECK-NEXT: [[RHS:%.*]] = or i8 [[RHS_IN:%.*]], 1
361+
; CHECK-NEXT: [[LBO:%.*]] = or i8 [[RHS]], [[Y_IN:%.*]]
362+
; CHECK-NEXT: [[R:%.*]] = icmp ugt i8 [[LBO]], [[RHS]]
363+
; CHECK-NEXT: ret i1 [[R]]
364+
;
365+
%y = and i8 %y_in, -2
366+
%rhs = or i8 %rhs_in, 1
367+
%lbo = or i8 %y, %rhs
368+
%r = icmp ugt i8 %lbo, %rhs
369+
ret i1 %r
370+
}
371+
372+
define i1 @pr64610(ptr %b) {
373+
; CHECK-LABEL: @pr64610(
374+
; CHECK-NEXT: [[V:%.*]] = load i1, ptr [[B:%.*]], align 2
375+
; CHECK-NEXT: [[S:%.*]] = select i1 [[V]], i32 74, i32 0
376+
; CHECK-NEXT: [[OR:%.*]] = or i32 [[S]], 1
377+
; CHECK-NEXT: [[R:%.*]] = icmp ugt i32 [[OR]], [[S]]
378+
; CHECK-NEXT: ret i1 [[R]]
379+
;
380+
%v = load i1, ptr %b, align 2
381+
%s = select i1 %v, i32 74, i32 0
382+
%or = or i32 %s, 1
383+
%r = icmp ugt i32 %or, %s
384+
ret i1 %r
385+
}

0 commit comments

Comments
 (0)