1+ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+ ; RUN: opt < %s -passes=instcombine -S | FileCheck %s --check-prefixes=CHECK,CONSTVEC
3+ ; RUN: opt < %s -passes=instcombine -S -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=CHECK,CONSTSPLAT
4+
5+ define i32 @add_select_cmp_and1 (i32 %in ) {
6+ ; CHECK-LABEL: @add_select_cmp_and1(
7+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
8+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
9+ ; CHECK-NEXT: ret i32 [[OUT]]
10+ ;
11+ %bitop0 = and i32 %in , 1
12+ %cmp0 = icmp eq i32 %bitop0 , 0
13+ %bitop1 = and i32 %in , 2
14+ %cmp1 = icmp eq i32 %bitop1 , 0
15+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
16+ %sel1 = select i1 %cmp1 , i32 0 , i32 144
17+ %out = or disjoint i32 %sel0 , %sel1
18+ ret i32 %out
19+ }
20+
21+ define i32 @add_select_cmp_and2 (i32 %in ) {
22+ ; CHECK-LABEL: @add_select_cmp_and2(
23+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 5
24+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
25+ ; CHECK-NEXT: ret i32 [[OUT]]
26+ ;
27+ %bitop0 = and i32 %in , 1
28+ %cmp0 = icmp eq i32 %bitop0 , 0
29+ %bitop1 = and i32 %in , 4
30+ %cmp1 = icmp eq i32 %bitop1 , 0
31+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
32+ %sel1 = select i1 %cmp1 , i32 0 , i32 288
33+ %out = or disjoint i32 %sel0 , %sel1
34+ ret i32 %out
35+ }
36+
37+ define i32 @add_select_cmp_and3 (i32 %in ) {
38+ ; CHECK-LABEL: @add_select_cmp_and3(
39+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
40+ ; CHECK-NEXT: [[TEMP:%.*]] = mul nuw nsw i32 [[TMP1]], 72
41+ ; CHECK-NEXT: [[BITOP2:%.*]] = and i32 [[IN]], 4
42+ ; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[BITOP2]], 0
43+ ; CHECK-NEXT: [[SEL2:%.*]] = select i1 [[CMP2]], i32 0, i32 288
44+ ; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[TEMP]], [[SEL2]]
45+ ; CHECK-NEXT: ret i32 [[OUT]]
46+ ;
47+ %bitop0 = and i32 %in , 1
48+ %cmp0 = icmp eq i32 %bitop0 , 0
49+ %bitop1 = and i32 %in , 2
50+ %cmp1 = icmp eq i32 %bitop1 , 0
51+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
52+ %sel1 = select i1 %cmp1 , i32 0 , i32 144
53+ %temp = or disjoint i32 %sel0 , %sel1
54+ %bitop2 = and i32 %in , 4
55+ %cmp2 = icmp eq i32 %bitop2 , 0
56+ %sel2 = select i1 %cmp2 , i32 0 , i32 288
57+ %out = or disjoint i32 %temp , %sel2
58+ ret i32 %out
59+ }
60+
61+ define i32 @add_select_cmp_and4 (i32 %in ) {
62+ ; CHECK-LABEL: @add_select_cmp_and4(
63+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
64+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
65+ ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[IN]], 12
66+ ; CHECK-NEXT: [[TEMP3:%.*]] = mul nuw nsw i32 [[TMP2]], 72
67+ ; CHECK-NEXT: [[OUT1:%.*]] = or disjoint i32 [[OUT]], [[TEMP3]]
68+ ; CHECK-NEXT: ret i32 [[OUT1]]
69+ ;
70+ %bitop0 = and i32 %in , 1
71+ %cmp0 = icmp eq i32 %bitop0 , 0
72+ %bitop1 = and i32 %in , 2
73+ %cmp1 = icmp eq i32 %bitop1 , 0
74+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
75+ %sel1 = select i1 %cmp1 , i32 0 , i32 144
76+ %temp = or disjoint i32 %sel0 , %sel1
77+ %bitop2 = and i32 %in , 4
78+ %cmp2 = icmp eq i32 %bitop2 , 0
79+ %bitop3 = and i32 %in , 8
80+ %cmp3 = icmp eq i32 %bitop3 , 0
81+ %sel2 = select i1 %cmp2 , i32 0 , i32 288
82+ %sel3 = select i1 %cmp3 , i32 0 , i32 576
83+ %temp2 = or disjoint i32 %sel2 , %sel3
84+ %out = or disjoint i32 %temp , %temp2
85+ ret i32 %out
86+ }
87+
88+ define i32 @add_select_cmp_and_pred1 (i32 %in ) {
89+ ; CHECK-LABEL: @add_select_cmp_and_pred1(
90+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
91+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
92+ ; CHECK-NEXT: ret i32 [[OUT]]
93+ ;
94+ %bitop0 = and i32 %in , 1
95+ %cmp0 = icmp ne i32 %bitop0 , 0
96+ %bitop1 = and i32 %in , 2
97+ %cmp1 = icmp eq i32 %bitop1 , 0
98+ %sel0 = select i1 %cmp0 , i32 72 , i32 0
99+ %sel1 = select i1 %cmp1 , i32 0 , i32 144
100+ %out = or disjoint i32 %sel0 , %sel1
101+ ret i32 %out
102+ }
103+
104+ define i32 @add_select_cmp_and_pred2 (i32 %in ) {
105+ ; CHECK-LABEL: @add_select_cmp_and_pred2(
106+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
107+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
108+ ; CHECK-NEXT: ret i32 [[OUT]]
109+ ;
110+ %bitop0 = and i32 %in , 1
111+ %cmp0 = icmp eq i32 %bitop0 , 0
112+ %bitop1 = and i32 %in , 2
113+ %cmp1 = icmp ne i32 %bitop1 , 0
114+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
115+ %sel1 = select i1 %cmp1 , i32 144 , i32 0
116+ %out = or disjoint i32 %sel0 , %sel1
117+ ret i32 %out
118+ }
119+
120+ define i32 @add_select_cmp_and_pred3 (i32 %in ) {
121+ ; CHECK-LABEL: @add_select_cmp_and_pred3(
122+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
123+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
124+ ; CHECK-NEXT: ret i32 [[OUT]]
125+ ;
126+ %bitop0 = and i32 %in , 1
127+ %cmp0 = icmp ne i32 %bitop0 , 0
128+ %bitop1 = and i32 %in , 2
129+ %cmp1 = icmp ne i32 %bitop1 , 0
130+ %sel0 = select i1 %cmp0 , i32 72 , i32 0
131+ %sel1 = select i1 %cmp1 , i32 144 , i32 0
132+ %out = or disjoint i32 %sel0 , %sel1
133+ ret i32 %out
134+ }
135+
136+ define i32 @add_select_cmp_trunc (i32 %in ) {
137+ ; CHECK-LABEL: @add_select_cmp_trunc(
138+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
139+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
140+ ; CHECK-NEXT: ret i32 [[OUT]]
141+ ;
142+ %cmp0 = trunc i32 %in to i1
143+ %bitop1 = and i32 %in , 2
144+ %cmp1 = icmp eq i32 %bitop1 , 0
145+ %sel0 = select i1 %cmp0 , i32 72 , i32 0
146+ %sel1 = select i1 %cmp1 , i32 0 , i32 144
147+ %out = or disjoint i32 %sel0 , %sel1
148+ ret i32 %out
149+ }
150+
151+ define i32 @add_select_cmp_trunc1 (i32 %in ) {
152+ ; CHECK-LABEL: @add_select_cmp_trunc1(
153+ ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[IN:%.*]], 3
154+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw i32 [[TMP1]], 72
155+ ; CHECK-NEXT: ret i32 [[OUT]]
156+ ;
157+ %cmp0 = trunc i32 %in to i1
158+ %bitop1 = and i32 %in , 2
159+ %cmp1 = icmp ne i32 %bitop1 , 0
160+ %sel0 = select i1 %cmp0 , i32 72 , i32 0
161+ %sel1 = select i1 %cmp1 , i32 144 , i32 0
162+ %out = or disjoint i32 %sel0 , %sel1
163+ ret i32 %out
164+ }
165+
166+
167+ define i32 @add_select_cmp_and_const_mismatch (i32 %in ) {
168+ ; CHECK-LABEL: @add_select_cmp_and_const_mismatch(
169+ ; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
170+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
171+ ; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN]], 2
172+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[BITOP1]], 0
173+ ; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
174+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 288
175+ ; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
176+ ; CHECK-NEXT: ret i32 [[OUT]]
177+ ;
178+ %bitop0 = and i32 %in , 1
179+ %cmp0 = icmp eq i32 %bitop0 , 0
180+ %bitop1 = and i32 %in , 2
181+ %cmp1 = icmp eq i32 %bitop1 , 0
182+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
183+ %sel1 = select i1 %cmp1 , i32 0 , i32 288
184+ %out = or disjoint i32 %sel0 , %sel1
185+ ret i32 %out
186+ }
187+
188+ define i32 @add_select_cmp_and_value_mismatch (i32 %in , i32 %in1 ) {
189+ ; CHECK-LABEL: @add_select_cmp_and_value_mismatch(
190+ ; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
191+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
192+ ; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN1:%.*]], 2
193+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[BITOP1]], 0
194+ ; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
195+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 144
196+ ; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
197+ ; CHECK-NEXT: ret i32 [[OUT]]
198+ ;
199+ %bitop0 = and i32 %in , 1
200+ %cmp0 = icmp eq i32 %bitop0 , 0
201+ %bitop1 = and i32 %in1 , 2
202+ %cmp1 = icmp eq i32 %bitop1 , 0
203+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
204+ %sel1 = select i1 %cmp1 , i32 0 , i32 144
205+ %out = or disjoint i32 %sel0 , %sel1
206+ ret i32 %out
207+ }
208+
209+ define i32 @add_select_cmp_and_negative (i32 %in ) {
210+ ; CHECK-LABEL: @add_select_cmp_and_negative(
211+ ; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
212+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
213+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[IN]], 2
214+ ; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
215+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 -144
216+ ; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
217+ ; CHECK-NEXT: ret i32 [[OUT]]
218+ ;
219+ %bitop0 = and i32 %in , 1
220+ %cmp0 = icmp eq i32 %bitop0 , 0
221+ %bitop1 = and i32 %in , -2
222+ %cmp1 = icmp eq i32 %bitop1 , 0
223+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
224+ %sel1 = select i1 %cmp1 , i32 0 , i32 -144
225+ %out = or disjoint i32 %sel0 , %sel1
226+ ret i32 %out
227+ }
228+
229+ define i32 @add_select_cmp_and_bitsel_overlap (i32 %in ) {
230+ ; CHECK-LABEL: @add_select_cmp_and_bitsel_overlap(
231+ ; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 2
232+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
233+ ; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 144
234+ ; CHECK-NEXT: ret i32 [[SEL0]]
235+ ;
236+ %bitop0 = and i32 %in , 2
237+ %cmp0 = icmp eq i32 %bitop0 , 0
238+ %bitop1 = and i32 %in , 2
239+ %cmp1 = icmp eq i32 %bitop1 , 0
240+ %sel0 = select i1 %cmp0 , i32 0 , i32 144
241+ %sel1 = select i1 %cmp1 , i32 0 , i32 144
242+ %out = or disjoint i32 %sel0 , %sel1
243+ ret i32 %out
244+ }
245+
246+ ; We cannot combine into and-mul, as %bitop1 may not be exactly 6
247+
248+ define i32 @add_select_cmp_and_multbit_mask (i32 %in ) {
249+ ; CHECK-LABEL: @add_select_cmp_and_multbit_mask(
250+ ; CHECK-NEXT: [[BITOP0:%.*]] = and i32 [[IN:%.*]], 1
251+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i32 [[BITOP0]], 0
252+ ; CHECK-NEXT: [[BITOP1:%.*]] = and i32 [[IN]], 6
253+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[BITOP1]], 0
254+ ; CHECK-NEXT: [[SEL0:%.*]] = select i1 [[CMP0]], i32 0, i32 72
255+ ; CHECK-NEXT: [[SEL1:%.*]] = select i1 [[CMP1]], i32 0, i32 432
256+ ; CHECK-NEXT: [[OUT:%.*]] = or disjoint i32 [[SEL0]], [[SEL1]]
257+ ; CHECK-NEXT: ret i32 [[OUT]]
258+ ;
259+ %bitop0 = and i32 %in , 1
260+ %cmp0 = icmp eq i32 %bitop0 , 0
261+ %bitop1 = and i32 %in , 6
262+ %cmp1 = icmp eq i32 %bitop1 , 0
263+ %sel0 = select i1 %cmp0 , i32 0 , i32 72
264+ %sel1 = select i1 %cmp1 , i32 0 , i32 432
265+ %out = or disjoint i32 %sel0 , %sel1
266+ ret i32 %out
267+ }
268+
269+
270+ define <2 x i32 > @add_select_cmp_vec (<2 x i32 > %in ) {
271+ ; CHECK-LABEL: @add_select_cmp_vec(
272+ ; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[IN:%.*]], splat (i32 3)
273+ ; CHECK-NEXT: [[OUT:%.*]] = mul nuw nsw <2 x i32> [[TMP1]], splat (i32 72)
274+ ; CHECK-NEXT: ret <2 x i32> [[OUT]]
275+ ;
276+ %bitop0 = and <2 x i32 > %in , <i32 1 , i32 1 >
277+ %cmp0 = icmp eq <2 x i32 > %bitop0 , <i32 0 , i32 0 >
278+ %bitop1 = and <2 x i32 > %in , <i32 2 , i32 2 >
279+ %cmp1 = icmp eq <2 x i32 > %bitop1 , <i32 0 , i32 0 >
280+ %sel0 = select <2 x i1 > %cmp0 , <2 x i32 > <i32 0 , i32 0 >, <2 x i32 > <i32 72 , i32 72 >
281+ %sel1 = select <2 x i1 > %cmp1 , <2 x i32 > <i32 0 , i32 0 >, <2 x i32 > <i32 144 , i32 144 >
282+ %out = or disjoint <2 x i32 > %sel0 , %sel1
283+ ret <2 x i32 > %out
284+ }
285+
286+ define <2 x i32 > @add_select_cmp_vec_poison (<2 x i32 > %in ) {
287+ ; CHECK-LABEL: @add_select_cmp_vec_poison(
288+ ; CHECK-NEXT: [[BITOP0:%.*]] = and <2 x i32> [[IN:%.*]], splat (i32 1)
289+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp eq <2 x i32> [[BITOP0]], zeroinitializer
290+ ; CHECK-NEXT: [[BITOP1:%.*]] = and <2 x i32> [[IN]], splat (i32 2)
291+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[BITOP1]], zeroinitializer
292+ ; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> zeroinitializer, <2 x i32> <i32 poison, i32 144>
293+ ; CHECK-NEXT: [[OUT:%.*]] = select <2 x i1> [[CMP0]], <2 x i32> [[SEL1]], <2 x i32> <i32 72, i32 poison>
294+ ; CHECK-NEXT: ret <2 x i32> [[OUT]]
295+ ;
296+ %bitop0 = and <2 x i32 > %in , <i32 1 , i32 1 >
297+ %cmp0 = icmp eq <2 x i32 > %bitop0 , <i32 0 , i32 0 >
298+ %bitop1 = and <2 x i32 > %in , <i32 2 , i32 2 >
299+ %cmp1 = icmp eq <2 x i32 > %bitop1 , <i32 0 , i32 0 >
300+ %sel0 = select <2 x i1 > %cmp0 , <2 x i32 > <i32 0 , i32 0 >, <2 x i32 > <i32 72 , i32 poison>
301+ %sel1 = select <2 x i1 > %cmp1 , <2 x i32 > <i32 0 , i32 0 >, <2 x i32 > <i32 poison, i32 144 >
302+ %out = or disjoint <2 x i32 > %sel0 , %sel1
303+ ret <2 x i32 > %out
304+ }
305+
306+ define <2 x i32 > @add_select_cmp_vec_nonunique (<2 x i32 > %in ) {
307+ ; CHECK-LABEL: @add_select_cmp_vec_nonunique(
308+ ; CHECK-NEXT: [[BITOP0:%.*]] = and <2 x i32> [[IN:%.*]], <i32 1, i32 2>
309+ ; CHECK-NEXT: [[CMP0:%.*]] = icmp eq <2 x i32> [[BITOP0]], zeroinitializer
310+ ; CHECK-NEXT: [[BITOP1:%.*]] = and <2 x i32> [[IN]], <i32 4, i32 8>
311+ ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq <2 x i32> [[BITOP1]], zeroinitializer
312+ ; CHECK-NEXT: [[SEL0:%.*]] = select <2 x i1> [[CMP0]], <2 x i32> zeroinitializer, <2 x i32> <i32 72, i32 144>
313+ ; CHECK-NEXT: [[SEL1:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> zeroinitializer, <2 x i32> <i32 288, i32 576>
314+ ; CHECK-NEXT: [[OUT:%.*]] = or disjoint <2 x i32> [[SEL0]], [[SEL1]]
315+ ; CHECK-NEXT: ret <2 x i32> [[OUT]]
316+ ;
317+ %bitop0 = and <2 x i32 > %in , <i32 1 , i32 2 >
318+ %cmp0 = icmp eq <2 x i32 > %bitop0 , <i32 0 , i32 0 >
319+ %bitop1 = and <2 x i32 > %in , <i32 4 , i32 8 >
320+ %cmp1 = icmp eq <2 x i32 > %bitop1 , <i32 0 , i32 0 >
321+ %sel0 = select <2 x i1 > %cmp0 , <2 x i32 > <i32 0 , i32 0 >, <2 x i32 > <i32 72 , i32 144 >
322+ %sel1 = select <2 x i1 > %cmp1 , <2 x i32 > <i32 0 , i32 0 >, <2 x i32 > <i32 288 , i32 576 >
323+ %out = or disjoint <2 x i32 > %sel0 , %sel1
324+ ret <2 x i32 > %out
325+ }
326+ ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
327+ ; CONSTSPLAT: {{.*}}
328+ ; CONSTVEC: {{.*}}
0 commit comments