Skip to content

Commit b336f9d

Browse files
committed
[InstCombine] Test cases for D154937
Create test cases for the following two folds: (icmp eq X, C) | (icmp ult Other, (X - C)) -> (icmp ule Other, (X - (C + 1))) (icmp ne X, C) & (icmp uge Other, (X - C)) -> (icmp ugt Other, (X - (C + 1))) Differential Revision: https://reviews.llvm.org/D154938
1 parent 65ef4d4 commit b336f9d

File tree

1 file changed

+294
-0
lines changed

1 file changed

+294
-0
lines changed
Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2+
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3+
4+
; Tests for foldAndOrOfICmpEqConstantAndICmp
5+
; https://github.com/llvm/llvm-project/issues/63749
6+
7+
; ==============================================================================
8+
; (icmp eq X, C) | (icmp ult Other, (X - C)) -> (icmp ule Other, (X - (C + 1)))
9+
; (icmp ne X, C) & (icmp uge Other, (X - C)) -> (icmp ugt Other, (X - (C + 1)))
10+
; ==============================================================================
11+
12+
; ==============================================================================
13+
; Basic tests
14+
; ==============================================================================
15+
define i1 @eq_basic(i8 %x, i8 %y) {
16+
; CHECK-LABEL: define i1 @eq_basic
17+
; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
18+
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], -1
19+
; CHECK-NEXT: [[OR:%.*]] = icmp uge i8 [[TMP1]], [[Y]]
20+
; CHECK-NEXT: ret i1 [[OR]]
21+
;
22+
%c1 = icmp eq i8 %x, 0
23+
%c2 = icmp ugt i8 %x, %y
24+
%or = or i1 %c1, %c2
25+
ret i1 %or
26+
}
27+
28+
define i1 @ne_basic_equal_5(i8 %x, i8 %y) {
29+
; CHECK-LABEL: define i1 @ne_basic_equal_5
30+
; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
31+
; CHECK-NEXT: [[SUB:%.*]] = add i8 [[X]], -5
32+
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X]], 5
33+
; CHECK-NEXT: [[C2:%.*]] = icmp ule i8 [[SUB]], [[Y]]
34+
; CHECK-NEXT: [[AND:%.*]] = and i1 [[C1]], [[C2]]
35+
; CHECK-NEXT: ret i1 [[AND]]
36+
;
37+
%sub = add i8 %x, -5
38+
%c1 = icmp ne i8 %x, 5
39+
%c2 = icmp ule i8 %sub, %y
40+
%and = and i1 %c1, %c2
41+
ret i1 %and
42+
}
43+
44+
define i1 @eq_basic_equal_minus_1(i8 %x, i8 %y) {
45+
; CHECK-LABEL: define i1 @eq_basic_equal_minus_1
46+
; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
47+
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1
48+
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X]], -1
49+
; CHECK-NEXT: [[C2:%.*]] = icmp ugt i8 [[ADD]], [[Y]]
50+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[C1]], [[C2]]
51+
; CHECK-NEXT: ret i1 [[OR]]
52+
;
53+
%add = add i8 %x, 1
54+
%c1 = icmp eq i8 %x, -1
55+
%c2 = icmp ugt i8 %add, %y
56+
%or = or i1 %c1, %c2
57+
ret i1 %or
58+
}
59+
60+
define i1 @ne_basic_equal_minus_7(i8 %x, i8 %y) {
61+
; CHECK-LABEL: define i1 @ne_basic_equal_minus_7
62+
; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
63+
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 7
64+
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X]], -7
65+
; CHECK-NEXT: [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
66+
; CHECK-NEXT: [[AND:%.*]] = and i1 [[C1]], [[C2]]
67+
; CHECK-NEXT: ret i1 [[AND]]
68+
;
69+
%add = add i8 %x, 7
70+
%c1 = icmp ne i8 %x, -7
71+
%c2 = icmp ule i8 %add, %y
72+
%and = and i1 %c1, %c2
73+
ret i1 %and
74+
}
75+
76+
define i1 @eq_basic_unequal(i8 %x, i8 %y) {
77+
; CHECK-LABEL: define i1 @eq_basic_unequal
78+
; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
79+
; CHECK-NEXT: [[SUB:%.*]] = add i8 [[X]], -5
80+
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X]], 6
81+
; CHECK-NEXT: [[C2:%.*]] = icmp ugt i8 [[SUB]], [[Y]]
82+
; CHECK-NEXT: [[OR:%.*]] = or i1 [[C1]], [[C2]]
83+
; CHECK-NEXT: ret i1 [[OR]]
84+
;
85+
%sub = add i8 %x, -5
86+
%c1 = icmp eq i8 %x, 6
87+
%c2 = icmp ugt i8 %sub, %y
88+
%or = or i1 %c1, %c2
89+
ret i1 %or
90+
}
91+
92+
define i1 @ne_basic_unequal(i8 %x, i8 %y) {
93+
; CHECK-LABEL: define i1 @ne_basic_unequal
94+
; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
95+
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 7
96+
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X]], -4
97+
; CHECK-NEXT: [[C2:%.*]] = icmp ule i8 [[ADD]], [[Y]]
98+
; CHECK-NEXT: [[AND:%.*]] = and i1 [[C1]], [[C2]]
99+
; CHECK-NEXT: ret i1 [[AND]]
100+
;
101+
%add = add i8 %x, 7
102+
%c1 = icmp ne i8 %x, -4
103+
%c2 = icmp ule i8 %add, %y
104+
%and = and i1 %c1, %c2
105+
ret i1 %and
106+
}
107+
108+
; ==============================================================================
109+
; Tests with multiple uses
110+
; ==============================================================================
111+
define i1 @eq_multi_c1(i8 %x, i8 %y) {
112+
; CHECK-LABEL: define i1 @eq_multi_c1
113+
; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
114+
; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[X]], 0
115+
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], -1
116+
; CHECK-NEXT: [[OR:%.*]] = icmp uge i8 [[TMP1]], [[Y]]
117+
; CHECK-NEXT: call void @use(i1 [[C1]])
118+
; CHECK-NEXT: ret i1 [[OR]]
119+
;
120+
%c1 = icmp eq i8 %x, 0
121+
%c2 = icmp ugt i8 %x, %y
122+
%or = or i1 %c1, %c2
123+
call void @use(i1 %c1)
124+
ret i1 %or
125+
}
126+
127+
define i1 @ne_multi_c2(i8 %x, i8 %y) {
128+
; CHECK-LABEL: define i1 @ne_multi_c2
129+
; CHECK-SAME: (i8 [[X:%.*]], i8 [[Y:%.*]]) {
130+
; CHECK-NEXT: [[C2:%.*]] = icmp ule i8 [[X]], [[Y]]
131+
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], -1
132+
; CHECK-NEXT: [[AND:%.*]] = icmp ult i8 [[TMP1]], [[Y]]
133+
; CHECK-NEXT: call void @use(i1 [[C2]])
134+
; CHECK-NEXT: ret i1 [[AND]]
135+
;
136+
%c1 = icmp ne i8 %x, 0
137+
%c2 = icmp ule i8 %x, %y
138+
%and = and i1 %c1, %c2
139+
call void @use(i1 %c2)
140+
ret i1 %and
141+
}
142+
143+
; ==============================================================================
144+
; Tests with vector types
145+
; ==============================================================================
146+
define <2 x i1> @eq_vector(<2 x i8> %x, <2 x i8> %y) {
147+
; CHECK-LABEL: define <2 x i1> @eq_vector
148+
; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
149+
; CHECK-NEXT: [[TMP1:%.*]] = add <2 x i8> [[X]], <i8 -1, i8 -1>
150+
; CHECK-NEXT: [[OR:%.*]] = icmp uge <2 x i8> [[TMP1]], [[Y]]
151+
; CHECK-NEXT: ret <2 x i1> [[OR]]
152+
;
153+
%c1 = icmp eq <2 x i8> %x, <i8 0, i8 0>
154+
%c2 = icmp ugt <2 x i8> %x, %y
155+
%or = or <2 x i1> %c1, %c2
156+
ret <2 x i1> %or
157+
}
158+
159+
define <2 x i1> @ne_vector_equal_5(<2 x i8> %x, <2 x i8> %y) {
160+
; CHECK-LABEL: define <2 x i1> @ne_vector_equal_5
161+
; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
162+
; CHECK-NEXT: [[SUB:%.*]] = add <2 x i8> [[X]], <i8 -5, i8 -5>
163+
; CHECK-NEXT: [[C1:%.*]] = icmp ne <2 x i8> [[X]], <i8 5, i8 5>
164+
; CHECK-NEXT: [[C2:%.*]] = icmp ule <2 x i8> [[SUB]], [[Y]]
165+
; CHECK-NEXT: [[AND:%.*]] = and <2 x i1> [[C1]], [[C2]]
166+
; CHECK-NEXT: ret <2 x i1> [[AND]]
167+
;
168+
%sub = add <2 x i8> %x, <i8 -5, i8 -5>
169+
%c1 = icmp ne <2 x i8> %x, <i8 5, i8 5>
170+
%c2 = icmp ule <2 x i8> %sub, %y
171+
%and = and <2 x i1> %c1, %c2
172+
ret <2 x i1> %and
173+
}
174+
175+
define <2 x i1> @eq_vector_equal_minus_1(<2 x i8> %x, <2 x i8> %y) {
176+
; CHECK-LABEL: define <2 x i1> @eq_vector_equal_minus_1
177+
; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
178+
; CHECK-NEXT: [[ADD:%.*]] = add <2 x i8> [[X]], <i8 1, i8 1>
179+
; CHECK-NEXT: [[C1:%.*]] = icmp eq <2 x i8> [[X]], <i8 -1, i8 -1>
180+
; CHECK-NEXT: [[C2:%.*]] = icmp ugt <2 x i8> [[ADD]], [[Y]]
181+
; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[C1]], [[C2]]
182+
; CHECK-NEXT: ret <2 x i1> [[OR]]
183+
;
184+
%add = add <2 x i8> %x, <i8 1, i8 1>
185+
%c1 = icmp eq <2 x i8> %x, <i8 -1, i8 -1>
186+
%c2 = icmp ugt <2 x i8> %add, %y
187+
%or = or <2 x i1> %c1, %c2
188+
ret <2 x i1> %or
189+
}
190+
191+
define <2 x i1> @ne_vector_equal_minus_7(<2 x i8> %x, <2 x i8> %y) {
192+
; CHECK-LABEL: define <2 x i1> @ne_vector_equal_minus_7
193+
; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
194+
; CHECK-NEXT: [[ADD:%.*]] = add <2 x i8> [[X]], <i8 7, i8 7>
195+
; CHECK-NEXT: [[C1:%.*]] = icmp ne <2 x i8> [[X]], <i8 -7, i8 -7>
196+
; CHECK-NEXT: [[C2:%.*]] = icmp ule <2 x i8> [[ADD]], [[Y]]
197+
; CHECK-NEXT: [[AND:%.*]] = and <2 x i1> [[C1]], [[C2]]
198+
; CHECK-NEXT: ret <2 x i1> [[AND]]
199+
;
200+
%add = add <2 x i8> %x, <i8 7, i8 7>
201+
%c1 = icmp ne <2 x i8> %x, <i8 -7, i8 -7>
202+
%c2 = icmp ule <2 x i8> %add, %y
203+
%and = and <2 x i1> %c1, %c2
204+
ret <2 x i1> %and
205+
}
206+
207+
define <2 x i1> @eq_vector_unequal1(<2 x i8> %x, <2 x i8> %y) {
208+
; CHECK-LABEL: define <2 x i1> @eq_vector_unequal1
209+
; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
210+
; CHECK-NEXT: [[SUB:%.*]] = add <2 x i8> [[X]], <i8 -5, i8 -5>
211+
; CHECK-NEXT: [[C1:%.*]] = icmp eq <2 x i8> [[X]], <i8 2, i8 2>
212+
; CHECK-NEXT: [[C2:%.*]] = icmp ugt <2 x i8> [[SUB]], [[Y]]
213+
; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[C1]], [[C2]]
214+
; CHECK-NEXT: ret <2 x i1> [[OR]]
215+
;
216+
%sub = add <2 x i8> %x, <i8 -5, i8 -5>
217+
%c1 = icmp eq <2 x i8> %x, <i8 2, i8 2>
218+
%c2 = icmp ugt <2 x i8> %sub, %y
219+
%or = or <2 x i1> %c1, %c2
220+
ret <2 x i1> %or
221+
}
222+
223+
define <2 x i1> @ne_vector_unequal2(<2 x i8> %x, <2 x i8> %y) {
224+
; CHECK-LABEL: define <2 x i1> @ne_vector_unequal2
225+
; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
226+
; CHECK-NEXT: [[ADD:%.*]] = add <2 x i8> [[X]], <i8 7, i8 7>
227+
; CHECK-NEXT: [[C1:%.*]] = icmp ne <2 x i8> [[X]], <i8 -3, i8 -3>
228+
; CHECK-NEXT: [[C2:%.*]] = icmp ule <2 x i8> [[ADD]], [[Y]]
229+
; CHECK-NEXT: [[AND:%.*]] = and <2 x i1> [[C1]], [[C2]]
230+
; CHECK-NEXT: ret <2 x i1> [[AND]]
231+
;
232+
%add = add <2 x i8> %x, <i8 7, i8 7>
233+
%c1 = icmp ne <2 x i8> %x, <i8 -3, i8 -3>
234+
%c2 = icmp ule <2 x i8> %add, %y
235+
%and = and <2 x i1> %c1, %c2
236+
ret <2 x i1> %and
237+
}
238+
239+
; ==============================================================================
240+
; Tests with undef
241+
; ==============================================================================
242+
define <2 x i1> @eq_vector_undef(<2 x i8> %x, <2 x i8> %y) {
243+
; CHECK-LABEL: define <2 x i1> @eq_vector_undef
244+
; CHECK-SAME: (<2 x i8> [[X:%.*]], <2 x i8> [[Y:%.*]]) {
245+
; CHECK-NEXT: [[SUB:%.*]] = add <2 x i8> [[X]], <i8 -5, i8 -5>
246+
; CHECK-NEXT: [[C1:%.*]] = icmp eq <2 x i8> [[X]], <i8 5, i8 undef>
247+
; CHECK-NEXT: [[C2:%.*]] = icmp ugt <2 x i8> [[SUB]], [[Y]]
248+
; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[C1]], [[C2]]
249+
; CHECK-NEXT: ret <2 x i1> [[OR]]
250+
;
251+
%sub = add <2 x i8> %x, <i8 -5, i8 -5>
252+
%c1 = icmp eq <2 x i8> %x, <i8 5, i8 undef>
253+
%c2 = icmp ugt <2 x i8> %sub, %y
254+
%or = or <2 x i1> %c1, %c2
255+
ret <2 x i1> %or
256+
}
257+
258+
; ==============================================================================
259+
; Tests with values commuted
260+
; ==============================================================================
261+
define i1 @eq_commuted(i8 %x, i8 %py) {
262+
; CHECK-LABEL: define i1 @eq_commuted
263+
; CHECK-SAME: (i8 [[X:%.*]], i8 [[PY:%.*]]) {
264+
; CHECK-NEXT: [[Y:%.*]] = sdiv i8 43, [[PY]]
265+
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[X]], -1
266+
; CHECK-NEXT: [[OR:%.*]] = icmp uge i8 [[TMP1]], [[Y]]
267+
; CHECK-NEXT: ret i1 [[OR]]
268+
;
269+
%y = sdiv i8 43, %py ; thwart complexity-based canonicalization
270+
%c1 = icmp eq i8 %x, 0
271+
%c2 = icmp ult i8 %y, %x
272+
%or = or i1 %c1, %c2
273+
ret i1 %or
274+
}
275+
276+
define i1 @ne_commuted_equal_minus_1(i8 %x, i8 %py) {
277+
; CHECK-LABEL: define i1 @ne_commuted_equal_minus_1
278+
; CHECK-SAME: (i8 [[X:%.*]], i8 [[PY:%.*]]) {
279+
; CHECK-NEXT: [[Y:%.*]] = sdiv i8 42, [[PY]]
280+
; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], 1
281+
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 [[X]], -1
282+
; CHECK-NEXT: [[C2:%.*]] = icmp uge i8 [[Y]], [[ADD]]
283+
; CHECK-NEXT: [[AND:%.*]] = and i1 [[C1]], [[C2]]
284+
; CHECK-NEXT: ret i1 [[AND]]
285+
;
286+
%y = sdiv i8 42, %py ; thwart complexity-based canonicalization
287+
%add = add i8 %x, 1
288+
%c1 = icmp ne i8 %x, -1
289+
%c2 = icmp uge i8 %y, %add
290+
%and = and i1 %c1, %c2
291+
ret i1 %and
292+
}
293+
294+
declare void @use(i1)

0 commit comments

Comments
 (0)