Skip to content

Commit 769c2a5

Browse files
jrbyrnesarsenmdtcxzyw
authored andcommitted
[InstCombine] Combine and->cmp->sel->or-disjoint into and->mul (#135274)
While and->cmp->sel combines into and->mul may result in worse code on some targets, this combine should be uniformly beneficial. Proof: https://alive2.llvm.org/ce/z/MibAcN --------- Co-authored-by: Matt Arsenault <[email protected]> Co-authored-by: Yingwei Zheng <[email protected]>
1 parent 723bc5c commit 769c2a5

File tree

2 files changed

+371
-0
lines changed

2 files changed

+371
-0
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3674,6 +3674,49 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
36743674
foldAddLikeCommutative(I.getOperand(1), I.getOperand(0),
36753675
/*NSW=*/true, /*NUW=*/true))
36763676
return R;
3677+
3678+
Value *Cond0 = nullptr, *Cond1 = nullptr;
3679+
const APInt *Op0Eq = nullptr, *Op0Ne = nullptr;
3680+
const APInt *Op1Eq = nullptr, *Op1Ne = nullptr;
3681+
3682+
// (!(A & N) ? 0 : N * C) + (!(A & M) ? 0 : M * C) -> A & (N + M) * C
3683+
if (match(I.getOperand(0),
3684+
m_Select(m_Value(Cond0), m_APInt(Op0Eq), m_APInt(Op0Ne))) &&
3685+
match(I.getOperand(1),
3686+
m_Select(m_Value(Cond1), m_APInt(Op1Eq), m_APInt(Op1Ne)))) {
3687+
3688+
auto LHSDecompose =
3689+
decomposeBitTest(Cond0, /*LookThruTrunc=*/true,
3690+
/*AllowNonZeroC=*/false, /*DecomposeAnd=*/true);
3691+
auto RHSDecompose =
3692+
decomposeBitTest(Cond1, /*LookThruTrunc=*/true,
3693+
/*AllowNonZeroC=*/false, /*DecomposeAnd=*/true);
3694+
3695+
if (LHSDecompose && RHSDecompose && LHSDecompose->X == RHSDecompose->X &&
3696+
RHSDecompose->Mask.isPowerOf2() && LHSDecompose->Mask.isPowerOf2() &&
3697+
LHSDecompose->Mask != RHSDecompose->Mask) {
3698+
assert(ICmpInst::isEquality(LHSDecompose->Pred));
3699+
if (LHSDecompose->Pred == ICmpInst::ICMP_NE)
3700+
std::swap(Op0Eq, Op0Ne);
3701+
if (RHSDecompose->Pred == ICmpInst::ICMP_NE)
3702+
std::swap(Op1Eq, Op1Ne);
3703+
3704+
if (!Op0Ne->isZero() && !Op1Ne->isZero() && Op0Eq->isZero() &&
3705+
Op1Eq->isZero() && Op0Ne->urem(LHSDecompose->Mask).isZero() &&
3706+
Op1Ne->urem(RHSDecompose->Mask).isZero() &&
3707+
Op0Ne->udiv(LHSDecompose->Mask) ==
3708+
Op1Ne->udiv(RHSDecompose->Mask)) {
3709+
auto NewAnd = Builder.CreateAnd(
3710+
LHSDecompose->X,
3711+
ConstantInt::get(LHSDecompose->X->getType(),
3712+
(LHSDecompose->Mask + RHSDecompose->Mask)));
3713+
3714+
return BinaryOperator::CreateMul(
3715+
NewAnd, ConstantInt::get(NewAnd->getType(),
3716+
Op0Ne->udiv(LHSDecompose->Mask)));
3717+
}
3718+
}
3719+
}
36773720
}
36783721

36793722
Value *X, *Y;
Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
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

Comments
 (0)