Skip to content

Commit 65c071f

Browse files
committed
[Precommit] fold icmp of select with constants and invertible op
1 parent c358979 commit 65c071f

File tree

1 file changed

+342
-0
lines changed

1 file changed

+342
-0
lines changed
Lines changed: 342 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,342 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3+
4+
; shl nsw
5+
; scmp
6+
define i1 @shl_nsw_scmp(i8 %a, i1 %cond) {
7+
; CHECK-LABEL: define i1 @shl_nsw_scmp(
8+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
9+
; CHECK-NEXT: [[A_SHL:%.*]] = shl nsw i8 [[A]], 3
10+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 8, i8 16
11+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A_SHL]], [[SEL]]
12+
; CHECK-NEXT: ret i1 [[CMP]]
13+
;
14+
%a_shl = shl nsw i8 %a, 3
15+
%sel = select i1 %cond, i8 8, i8 16
16+
%cmp = icmp sgt i8 %a_shl, %sel
17+
ret i1 %cmp
18+
}
19+
; scmp commutative
20+
define i1 @c_shl_nsw_scmp(i8 %a, i1 %cond) {
21+
; CHECK-LABEL: define i1 @c_shl_nsw_scmp(
22+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
23+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 8, i8 16
24+
; CHECK-NEXT: [[A_SHL:%.*]] = shl nsw i8 [[A]], 3
25+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[SEL]], [[A_SHL]]
26+
; CHECK-NEXT: ret i1 [[CMP]]
27+
;
28+
%sel = select i1 %cond, i8 8, i8 16
29+
%a_shl = shl nsw i8 %a, 3
30+
%cmp = icmp sgt i8 %sel, %a_shl
31+
ret i1 %cmp
32+
}
33+
; scmp mismatch
34+
define i1 @shl_nsw_scmp_mismatch(i8 %a, i1 %cond) {
35+
; CHECK-LABEL: define i1 @shl_nsw_scmp_mismatch(
36+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
37+
; CHECK-NEXT: [[A_SHL:%.*]] = shl nsw i8 [[A]], 3
38+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 8, i8 1
39+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A_SHL]], [[SEL]]
40+
; CHECK-NEXT: ret i1 [[CMP]]
41+
;
42+
%a_shl = shl nsw i8 %a, 3
43+
%sel = select i1 %cond, i8 8, i8 1
44+
%cmp = icmp sgt i8 %a_shl, %sel
45+
ret i1 %cmp
46+
}
47+
; ucmp
48+
define i1 @shl_nsw_ucmp(i8 %a, i1 %cond) {
49+
; CHECK-LABEL: define i1 @shl_nsw_ucmp(
50+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
51+
; CHECK-NEXT: [[A_SHL:%.*]] = shl nsw i8 [[A]], 3
52+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 8, i8 24
53+
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i8 [[A_SHL]], [[SEL]]
54+
; CHECK-NEXT: ret i1 [[CMP]]
55+
;
56+
%a_shl = shl nsw i8 %a, 3
57+
%sel = select i1 %cond, i8 8, i8 24
58+
%cmp = icmp ugt i8 %a_shl, %sel
59+
ret i1 %cmp
60+
}
61+
62+
; shl nuw only ucmp/eq/ne
63+
; ucmp
64+
define i1 @shl_nuw_ucmp(i8 %a, i1 %cond) {
65+
; CHECK-LABEL: define i1 @shl_nuw_ucmp(
66+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
67+
; CHECK-NEXT: [[A_SHL:%.*]] = shl nuw i8 [[A]], 3
68+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 8, i8 32
69+
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[A_SHL]], [[SEL]]
70+
; CHECK-NEXT: ret i1 [[CMP]]
71+
;
72+
%a_shl = shl nuw i8 %a, 3
73+
%sel = select i1 %cond, i8 8, i8 32
74+
%cmp = icmp ult i8 %a_shl, %sel
75+
ret i1 %cmp
76+
}
77+
78+
; eq
79+
define i1 @shl_nuw_eqcmp(i8 %a, i1 %cond) {
80+
; CHECK-LABEL: define i1 @shl_nuw_eqcmp(
81+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
82+
; CHECK-NEXT: [[A_SHL:%.*]] = shl nuw i8 [[A]], 3
83+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 8, i8 64
84+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[SEL]], [[A_SHL]]
85+
; CHECK-NEXT: ret i1 [[CMP]]
86+
;
87+
%a_shl = shl nuw i8 %a, 3
88+
%sel = select i1 %cond, i8 8, i8 64
89+
%cmp = icmp eq i8 %sel, %a_shl
90+
ret i1 %cmp
91+
}
92+
93+
; scmp mismatch
94+
define i1 @shl_nuw_scmp(i8 %a, i1 %cond) {
95+
; CHECK-LABEL: define i1 @shl_nuw_scmp(
96+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
97+
; CHECK-NEXT: [[A_SHL:%.*]] = shl nuw i8 [[A]], 3
98+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 8, i8 32
99+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[A_SHL]], [[SEL]]
100+
; CHECK-NEXT: ret i1 [[CMP]]
101+
;
102+
%a_shl = shl nuw i8 %a, 3
103+
%sel = select i1 %cond, i8 8, i8 32
104+
%cmp = icmp slt i8 %a_shl, %sel
105+
ret i1 %cmp
106+
}
107+
108+
; ashr exact
109+
; ucmp
110+
define i1 @ashr_exact_ucmp(i8 %a, i1 %cond) {
111+
; CHECK-LABEL: define i1 @ashr_exact_ucmp(
112+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
113+
; CHECK-NEXT: [[A_SHL:%.*]] = ashr exact i8 [[A]], 2
114+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 12, i8 4
115+
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i8 [[A_SHL]], [[SEL]]
116+
; CHECK-NEXT: ret i1 [[CMP]]
117+
;
118+
%a_shl = ashr exact i8 %a, 2
119+
%sel = select i1 %cond, i8 12, i8 4
120+
%cmp = icmp uge i8 %a_shl, %sel
121+
ret i1 %cmp
122+
}
123+
; scmp
124+
define i1 @ashr_exact_scmp(i8 %a, i1 %cond) {
125+
; CHECK-LABEL: define i1 @ashr_exact_scmp(
126+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
127+
; CHECK-NEXT: [[A_SHL:%.*]] = ashr exact i8 [[A]], 2
128+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 8, i8 4
129+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A_SHL]], [[SEL]]
130+
; CHECK-NEXT: ret i1 [[CMP]]
131+
;
132+
%a_shl = ashr exact i8 %a, 2
133+
%sel = select i1 %cond, i8 8, i8 4
134+
%cmp = icmp sgt i8 %a_shl, %sel
135+
ret i1 %cmp
136+
}
137+
138+
; lshr exact only ucmp/eq/ne
139+
; ucmp
140+
define i1 @lshr_exact_ucmp(i8 %a, i1 %cond) {
141+
; CHECK-LABEL: define i1 @lshr_exact_ucmp(
142+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
143+
; CHECK-NEXT: [[A_SHL:%.*]] = lshr exact i8 [[A]], 1
144+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 1, i8 3
145+
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i8 [[A_SHL]], [[SEL]]
146+
; CHECK-NEXT: ret i1 [[CMP]]
147+
;
148+
%a_shl = lshr exact i8 %a, 1
149+
%sel = select i1 %cond, i8 1, i8 3
150+
%cmp = icmp ugt i8 %a_shl, %sel
151+
ret i1 %cmp
152+
}
153+
; scmp mismatch
154+
define i1 @lshr_exact_scmp(i8 %a, i1 %cond) {
155+
; CHECK-LABEL: define i1 @lshr_exact_scmp(
156+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
157+
; CHECK-NEXT: [[A_SHL:%.*]] = lshr exact i8 [[A]], 1
158+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 1, i8 3
159+
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign uge i8 [[A_SHL]], [[SEL]]
160+
; CHECK-NEXT: ret i1 [[CMP]]
161+
;
162+
%a_shl = lshr exact i8 %a, 1
163+
%sel = select i1 %cond, i8 1, i8 3
164+
%cmp = icmp sge i8 %a_shl, %sel
165+
ret i1 %cmp
166+
}
167+
168+
; zext only ucmp/eq/ne
169+
; ucmp
170+
define i1 @zext_ucmp(i8 %a, i16 %c0, i16 %c1, i1 %cond) {
171+
; CHECK-LABEL: define i1 @zext_ucmp(
172+
; CHECK-SAME: i8 [[A:%.*]], i16 [[C0:%.*]], i16 [[C1:%.*]], i1 [[COND:%.*]]) {
173+
; CHECK-NEXT: [[IDX:%.*]] = zext i8 [[A]] to i16
174+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i16 128, i16 64
175+
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i16 [[SEL]], [[IDX]]
176+
; CHECK-NEXT: ret i1 [[CMP]]
177+
;
178+
%idx = zext i8 %a to i16
179+
%sel = select i1 %cond, i16 128, i16 64
180+
%cmp = icmp ult i16 %idx, %sel
181+
ret i1 %cmp
182+
}
183+
; scmp mismatch
184+
define i1 @zext_scmp_mismatch(i8 %a, i16 %c0, i16 %c1, i1 %cond) {
185+
; CHECK-LABEL: define i1 @zext_scmp_mismatch(
186+
; CHECK-SAME: i8 [[A:%.*]], i16 [[C0:%.*]], i16 [[C1:%.*]], i1 [[COND:%.*]]) {
187+
; CHECK-NEXT: [[IDX:%.*]] = zext i8 [[A]] to i16
188+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i16 128, i16 64
189+
; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ugt i16 [[SEL]], [[IDX]]
190+
; CHECK-NEXT: ret i1 [[CMP]]
191+
;
192+
%idx = zext i8 %a to i16
193+
%sel = select i1 %cond, i16 128, i16 64
194+
%cmp = icmp slt i16 %idx, %sel
195+
ret i1 %cmp
196+
}
197+
198+
; sext
199+
; ucmp
200+
define i1 @sext_ucmp(i8 %a, i16 %c0, i16 %c1, i1 %cond) {
201+
; CHECK-LABEL: define i1 @sext_ucmp(
202+
; CHECK-SAME: i8 [[A:%.*]], i16 [[C0:%.*]], i16 [[C1:%.*]], i1 [[COND:%.*]]) {
203+
; CHECK-NEXT: [[IDX:%.*]] = sext i8 [[A]] to i16
204+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i16 -127, i16 126
205+
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i16 [[SEL]], [[IDX]]
206+
; CHECK-NEXT: ret i1 [[CMP]]
207+
;
208+
%idx = sext i8 %a to i16
209+
%sel = select i1 %cond, i16 -127, i16 126
210+
%cmp = icmp ult i16 %idx, %sel
211+
ret i1 %cmp
212+
}
213+
; ucmp mismatch
214+
define i1 @sext_ucmp_mismatch(i8 %a, i16 %c0, i16 %c1, i1 %cond) {
215+
; CHECK-LABEL: define i1 @sext_ucmp_mismatch(
216+
; CHECK-SAME: i8 [[A:%.*]], i16 [[C0:%.*]], i16 [[C1:%.*]], i1 [[COND:%.*]]) {
217+
; CHECK-NEXT: [[IDX:%.*]] = sext i8 [[A]] to i16
218+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i16 -129, i16 128
219+
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i16 [[SEL]], [[IDX]]
220+
; CHECK-NEXT: ret i1 [[CMP]]
221+
;
222+
%idx = sext i8 %a to i16
223+
%sel = select i1 %cond, i16 -129, i16 128
224+
%cmp = icmp ult i16 %idx, %sel
225+
ret i1 %cmp
226+
}
227+
; scmp
228+
define i1 @sext_scmp(i8 %a, i16 %c0, i16 %c1, i1 %cond) {
229+
; CHECK-LABEL: define i1 @sext_scmp(
230+
; CHECK-SAME: i8 [[A:%.*]], i16 [[C0:%.*]], i16 [[C1:%.*]], i1 [[COND:%.*]]) {
231+
; CHECK-NEXT: [[IDX:%.*]] = sext i8 [[A]] to i16
232+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i16 -5, i16 9
233+
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i16 [[SEL]], [[IDX]]
234+
; CHECK-NEXT: ret i1 [[CMP]]
235+
;
236+
%idx = sext i8 %a to i16
237+
%sel = select i1 %cond, i16 -5, i16 9
238+
%cmp = icmp slt i16 %idx, %sel
239+
ret i1 %cmp
240+
}
241+
242+
; or disjoint
243+
; ucmp
244+
define i1 @or_disjoint_ucmp(i8 %a, i1 %cond) {
245+
; CHECK-LABEL: define i1 @or_disjoint_ucmp(
246+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
247+
; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[A]], 3
248+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 11, i8 7
249+
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[OR]], [[SEL]]
250+
; CHECK-NEXT: ret i1 [[CMP]]
251+
;
252+
%or = or disjoint i8 %a, 3
253+
%sel = select i1 %cond, i8 11, i8 7
254+
%cmp = icmp ult i8 %or, %sel
255+
ret i1 %cmp
256+
}
257+
; scmp mismatch
258+
define i1 @or_disjoint_scmp(i8 %a, i1 %cond) {
259+
; CHECK-LABEL: define i1 @or_disjoint_scmp(
260+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
261+
; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[A]], 3
262+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 11, i8 7
263+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 [[OR]], [[SEL]]
264+
; CHECK-NEXT: ret i1 [[CMP]]
265+
;
266+
%or = or disjoint i8 %a, 3
267+
%sel = select i1 %cond, i8 11, i8 7
268+
%cmp = icmp slt i8 %or, %sel
269+
ret i1 %cmp
270+
}
271+
; mismatch constant '4' not disjoint
272+
define i1 @or_ucmp_mismatch(i8 %a, i1 %cond) {
273+
; CHECK-LABEL: define i1 @or_ucmp_mismatch(
274+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
275+
; CHECK-NEXT: [[OR:%.*]] = or disjoint i8 [[A]], 3
276+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 11, i8 4
277+
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[OR]], [[SEL]]
278+
; CHECK-NEXT: ret i1 [[CMP]]
279+
;
280+
%or = or disjoint i8 %a, 3
281+
%sel = select i1 %cond, i8 11, i8 4
282+
%cmp = icmp ult i8 %or, %sel
283+
ret i1 %cmp
284+
}
285+
286+
; sub only eq/ne
287+
define i1 @sub_eq(i8 %a, i1 %cond) {
288+
; CHECK-LABEL: define i1 @sub_eq(
289+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
290+
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], i8 4, i8 12
291+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A]], [[TMP1]]
292+
; CHECK-NEXT: ret i1 [[CMP]]
293+
;
294+
%sub = sub i8 %a, 5
295+
%sel = select i1 %cond, i8 -1, i8 7
296+
%cmp = icmp eq i8 %sub, %sel
297+
ret i1 %cmp
298+
}
299+
; ucmp mismatch
300+
define i1 @sub_ucmp(i8 %a, i1 %cond) {
301+
; CHECK-LABEL: define i1 @sub_ucmp(
302+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
303+
; CHECK-NEXT: [[TMP1:%.*]] = add i8 [[A]], -13
304+
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 [[TMP1]], -8
305+
; CHECK-NEXT: [[NOT_COND:%.*]] = xor i1 [[COND]], true
306+
; CHECK-NEXT: [[CMP:%.*]] = select i1 [[NOT_COND]], i1 [[CMP1]], i1 false
307+
; CHECK-NEXT: ret i1 [[CMP]]
308+
;
309+
%sub = sub i8 %a, 5
310+
%sel = select i1 %cond, i8 -1, i8 7
311+
%cmp = icmp ugt i8 %sub, %sel
312+
ret i1 %cmp
313+
}
314+
315+
; add only eq/ne
316+
define i1 @add_ne(i8 %a, i1 %cond) {
317+
; CHECK-LABEL: define i1 @add_ne(
318+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
319+
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND]], i8 -6, i8 2
320+
; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[A]], [[TMP1]]
321+
; CHECK-NEXT: ret i1 [[CMP]]
322+
;
323+
%sub = add i8 %a, 5
324+
%sel = select i1 %cond, i8 -1, i8 7
325+
%cmp = icmp ne i8 %sub, %sel
326+
ret i1 %cmp
327+
}
328+
329+
; xor only eq/ne
330+
define i1 @xor_eq(i8 %a, i1 %cond) {
331+
; CHECK-LABEL: define i1 @xor_eq(
332+
; CHECK-SAME: i8 [[A:%.*]], i1 [[COND:%.*]]) {
333+
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], i8 -1, i8 7
334+
; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[A]], [[SEL]]
335+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 5
336+
; CHECK-NEXT: ret i1 [[CMP]]
337+
;
338+
%sub = xor i8 %a, 5
339+
%sel = select i1 %cond, i8 -1, i8 7
340+
%cmp = icmp eq i8 %sub, %sel
341+
ret i1 %cmp
342+
}

0 commit comments

Comments
 (0)