xref: /llvm-project/llvm/test/Transforms/InstCombine/select-of-bittest.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4; https://bugs.llvm.org/show_bug.cgi?id=36950
5
6; These all should be just and+icmp, there should be no select.
7
8define i32 @and_lshr_and(i32 %arg) {
9; CHECK-LABEL: @and_lshr_and(
10; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 3
11; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
12; CHECK-NEXT:    [[T4:%.*]] = zext i1 [[TMP2]] to i32
13; CHECK-NEXT:    ret i32 [[T4]]
14;
15  %t = and i32 %arg, 1
16  %t1 = icmp eq i32 %t, 0
17  %t2 = lshr i32 %arg, 1
18  %t3 = and i32 %t2, 1
19  %t4 = select i1 %t1, i32 %t3, i32 1
20  ret i32 %t4
21}
22
23define <2 x i32> @and_lshr_and_splatvec(<2 x i32> %arg) {
24; CHECK-LABEL: @and_lshr_and_splatvec(
25; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], splat (i32 3)
26; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
27; CHECK-NEXT:    [[T4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
28; CHECK-NEXT:    ret <2 x i32> [[T4]]
29;
30  %t = and <2 x i32> %arg, <i32 1, i32 1>
31  %t1 = icmp eq <2 x i32> %t, zeroinitializer
32  %t2 = lshr <2 x i32> %arg, <i32 1, i32 1>
33  %t3 = and <2 x i32> %t2, <i32 1, i32 1>
34  %t4 = select <2 x i1> %t1, <2 x i32> %t3, <2 x i32> <i32 1, i32 1>
35  ret <2 x i32> %t4
36}
37
38define <2 x i32> @and_lshr_and_vec_v0(<2 x i32> %arg) {
39; CHECK-LABEL: @and_lshr_and_vec_v0(
40; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 3, i32 6>
41; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
42; CHECK-NEXT:    [[T4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
43; CHECK-NEXT:    ret <2 x i32> [[T4]]
44;
45  %t = and <2 x i32> %arg, <i32 1, i32 4> ; mask is not splat
46  %t1 = icmp eq <2 x i32> %t, zeroinitializer
47  %t2 = lshr <2 x i32> %arg, <i32 1, i32 1>
48  %t3 = and <2 x i32> %t2, <i32 1, i32 1>
49  %t4 = select <2 x i1> %t1, <2 x i32> %t3, <2 x i32> <i32 1, i32 1>
50  ret <2 x i32> %t4
51}
52
53define <2 x i32> @and_lshr_and_vec_v1(<2 x i32> %arg) {
54; CHECK-LABEL: @and_lshr_and_vec_v1(
55; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 3, i32 5>
56; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
57; CHECK-NEXT:    [[T4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
58; CHECK-NEXT:    ret <2 x i32> [[T4]]
59;
60  %t = and <2 x i32> %arg, <i32 1, i32 1>
61  %t1 = icmp eq <2 x i32> %t, zeroinitializer
62  %t2 = lshr <2 x i32> %arg, <i32 1, i32 2> ; shift is not splat
63  %t3 = and <2 x i32> %t2, <i32 1, i32 1>
64  %t4 = select <2 x i1> %t1, <2 x i32> %t3, <2 x i32> <i32 1, i32 1>
65  ret <2 x i32> %t4
66}
67
68define <2 x i32> @and_lshr_and_vec_v2(<2 x i32> %arg) {
69; CHECK-LABEL: @and_lshr_and_vec_v2(
70; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 12, i32 3>
71; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
72; CHECK-NEXT:    [[T4:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
73; CHECK-NEXT:    ret <2 x i32> [[T4]]
74;
75  %t = and <2 x i32> %arg, <i32 8, i32 1> ; mask is not splat
76  %t1 = icmp eq <2 x i32> %t, zeroinitializer
77  %t2 = lshr <2 x i32> %arg, <i32 2, i32 1> ; shift is not splat
78  %t3 = and <2 x i32> %t2, <i32 1, i32 1>
79  %t4 = select <2 x i1> %t1, <2 x i32> %t3, <2 x i32> <i32 1, i32 1>
80  ret <2 x i32> %t4
81}
82
83define <3 x i32> @and_lshr_and_vec_poison(<3 x i32> %arg) {
84; CHECK-LABEL: @and_lshr_and_vec_poison(
85; CHECK-NEXT:    [[TMP1:%.*]] = and <3 x i32> [[ARG:%.*]], <i32 3, i32 poison, i32 3>
86; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <3 x i32> [[TMP1]], zeroinitializer
87; CHECK-NEXT:    [[T4:%.*]] = zext <3 x i1> [[TMP2]] to <3 x i32>
88; CHECK-NEXT:    ret <3 x i32> [[T4]]
89;
90  %t = and <3 x i32> %arg, <i32 1, i32 poison, i32 1>
91  %t1 = icmp eq <3 x i32> %t, <i32 0, i32 poison, i32 0>
92  %t2 = lshr <3 x i32> %arg, <i32 1, i32 poison, i32 1>
93  %t3 = and <3 x i32> %t2, <i32 1, i32 poison, i32 1>
94  %t4 = select <3 x i1> %t1, <3 x i32> %t3, <3 x i32> <i32 1, i32 poison, i32 1>
95  ret <3 x i32> %t4
96}
97
98define i32 @and_and(i32 %arg) {
99; CHECK-LABEL: @and_and(
100; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ARG:%.*]], 3
101; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
102; CHECK-NEXT:    [[T3:%.*]] = zext i1 [[TMP2]] to i32
103; CHECK-NEXT:    ret i32 [[T3]]
104;
105  %t = and i32 %arg, 2
106  %t1 = icmp eq i32 %t, 0
107  %t2 = and i32 %arg, 1
108  %t3 = select i1 %t1, i32 %t2, i32 1
109  ret i32 %t3
110}
111
112define <2 x i32> @and_and_splatvec(<2 x i32> %arg) {
113; CHECK-LABEL: @and_and_splatvec(
114; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], splat (i32 3)
115; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
116; CHECK-NEXT:    [[T3:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
117; CHECK-NEXT:    ret <2 x i32> [[T3]]
118;
119  %t = and <2 x i32> %arg, <i32 2, i32 2>
120  %t1 = icmp eq <2 x i32> %t, zeroinitializer
121  %t2 = and <2 x i32> %arg, <i32 1, i32 1>
122  %t3 = select <2 x i1> %t1, <2 x i32> %t2, <2 x i32> <i32 1, i32 1>
123  ret <2 x i32> %t3
124}
125
126define <2 x i32> @and_and_vec(<2 x i32> %arg) {
127; CHECK-LABEL: @and_and_vec(
128; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 7, i32 3>
129; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer
130; CHECK-NEXT:    [[T3:%.*]] = zext <2 x i1> [[TMP2]] to <2 x i32>
131; CHECK-NEXT:    ret <2 x i32> [[T3]]
132;
133  %t = and <2 x i32> %arg, <i32 6, i32 2> ; mask is not splat
134  %t1 = icmp eq <2 x i32> %t, zeroinitializer
135  %t2 = and <2 x i32> %arg, <i32 1, i32 1>
136  %t3 = select <2 x i1> %t1, <2 x i32> %t2, <2 x i32> <i32 1, i32 1>
137  ret <2 x i32> %t3
138}
139
140define <3 x i32> @and_and_vec_poison(<3 x i32> %arg) {
141; CHECK-LABEL: @and_and_vec_poison(
142; CHECK-NEXT:    [[TMP1:%.*]] = and <3 x i32> [[ARG:%.*]], <i32 3, i32 poison, i32 3>
143; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <3 x i32> [[TMP1]], zeroinitializer
144; CHECK-NEXT:    [[T3:%.*]] = zext <3 x i1> [[TMP2]] to <3 x i32>
145; CHECK-NEXT:    ret <3 x i32> [[T3]]
146;
147  %t = and <3 x i32> %arg, <i32 2, i32 poison, i32 2>
148  %t1 = icmp eq <3 x i32> %t, <i32 0, i32 poison, i32 0>
149  %t2 = and <3 x i32> %arg, <i32 1, i32 poison, i32 1>
150  %t3 = select <3 x i1> %t1, <3 x i32> %t2, <3 x i32> <i32 1, i32 poison, i32 1>
151  ret <3 x i32> %t3
152}
153
154; ============================================================================ ;
155; Mask can be a variable, too.
156; ============================================================================ ;
157
158define i32 @f_var0(i32 %arg, i32 %arg1) {
159; CHECK-LABEL: @f_var0(
160; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 2
161; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[ARG:%.*]], [[TMP1]]
162; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
163; CHECK-NEXT:    [[T5:%.*]] = zext i1 [[TMP3]] to i32
164; CHECK-NEXT:    ret i32 [[T5]]
165;
166  %t = and i32 %arg, %arg1
167  %t2 = icmp eq i32 %t, 0
168  %t3 = lshr i32 %arg, 1
169  %t4 = and i32 %t3, 1
170  %t5 = select i1 %t2, i32 %t4, i32 1
171  ret i32 %t5
172}
173
174; Should be exactly as the previous one
175define i32 @f_var0_commutative_and(i32 %arg, i32 %arg1) {
176; CHECK-LABEL: @f_var0_commutative_and(
177; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 2
178; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[ARG:%.*]], [[TMP1]]
179; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
180; CHECK-NEXT:    [[T5:%.*]] = zext i1 [[TMP3]] to i32
181; CHECK-NEXT:    ret i32 [[T5]]
182;
183  %t = and i32 %arg1, %arg ; in different order
184  %t2 = icmp eq i32 %t, 0
185  %t3 = lshr i32 %arg, 1
186  %t4 = and i32 %t3, 1
187  %t5 = select i1 %t2, i32 %t4, i32 1
188  ret i32 %t5
189}
190
191define <2 x i32> @f_var0_splatvec(<2 x i32> %arg, <2 x i32> %arg1) {
192; CHECK-LABEL: @f_var0_splatvec(
193; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[ARG1:%.*]], splat (i32 2)
194; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[ARG:%.*]], [[TMP1]]
195; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
196; CHECK-NEXT:    [[T5:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32>
197; CHECK-NEXT:    ret <2 x i32> [[T5]]
198;
199  %t = and <2 x i32> %arg, %arg1
200  %t2 = icmp eq <2 x i32> %t, zeroinitializer
201  %t3 = lshr <2 x i32> %arg, <i32 1, i32 1>
202  %t4 = and <2 x i32> %t3, <i32 1, i32 1>
203  %t5 = select <2 x i1> %t2, <2 x i32> %t4, <2 x i32> <i32 1, i32 1>
204  ret <2 x i32> %t5
205}
206
207define <2 x i32> @f_var0_vec(<2 x i32> %arg, <2 x i32> %arg1) {
208; CHECK-LABEL: @f_var0_vec(
209; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[ARG1:%.*]], <i32 2, i32 4>
210; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[ARG:%.*]], [[TMP1]]
211; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
212; CHECK-NEXT:    [[T5:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32>
213; CHECK-NEXT:    ret <2 x i32> [[T5]]
214;
215  %t = and <2 x i32> %arg, %arg1
216  %t2 = icmp eq <2 x i32> %t, zeroinitializer
217  %t3 = lshr <2 x i32> %arg, <i32 1, i32 2> ; shift is not splat
218  %t4 = and <2 x i32> %t3, <i32 1, i32 1>
219  %t5 = select <2 x i1> %t2, <2 x i32> %t4, <2 x i32> <i32 1, i32 1>
220  ret <2 x i32> %t5
221}
222
223define <3 x i32> @f_var0_vec_poison(<3 x i32> %arg, <3 x i32> %arg1) {
224; CHECK-LABEL: @f_var0_vec_poison(
225; CHECK-NEXT:    [[TMP1:%.*]] = or <3 x i32> [[ARG1:%.*]], <i32 2, i32 poison, i32 2>
226; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[ARG:%.*]], [[TMP1]]
227; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
228; CHECK-NEXT:    [[T5:%.*]] = zext <3 x i1> [[TMP3]] to <3 x i32>
229; CHECK-NEXT:    ret <3 x i32> [[T5]]
230;
231  %t = and <3 x i32> %arg, %arg1
232  %t2 = icmp eq <3 x i32> %t, <i32 0, i32 poison, i32 0>
233  %t3 = lshr <3 x i32> %arg, <i32 1, i32 poison, i32 1>
234  %t4 = and <3 x i32> %t3, <i32 1, i32 poison, i32 1>
235  ; The second element of %t5 is poison because it is (poison ? poison : poison).
236  %t5 = select <3 x i1> %t2, <3 x i32> %t4, <3 x i32> <i32 1, i32 poison, i32 1>
237  ret <3 x i32> %t5
238}
239
240define i32 @f_var1(i32 %arg, i32 %arg1) {
241; CHECK-LABEL: @f_var1(
242; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 1
243; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[ARG:%.*]], [[TMP1]]
244; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
245; CHECK-NEXT:    [[T4:%.*]] = zext i1 [[TMP3]] to i32
246; CHECK-NEXT:    ret i32 [[T4]]
247;
248  %t = and i32 %arg, %arg1
249  %t2 = icmp eq i32 %t, 0
250  %t3 = and i32 %arg, 1
251  %t4 = select i1 %t2, i32 %t3, i32 1
252  ret i32 %t4
253}
254
255; Should be exactly as the previous one
256define i32 @f_var1_commutative_and(i32 %arg, i32 %arg1) {
257; CHECK-LABEL: @f_var1_commutative_and(
258; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[ARG1:%.*]], 1
259; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[ARG:%.*]], [[TMP1]]
260; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
261; CHECK-NEXT:    [[T4:%.*]] = zext i1 [[TMP3]] to i32
262; CHECK-NEXT:    ret i32 [[T4]]
263;
264  %t = and i32 %arg1, %arg ; in different order
265  %t2 = icmp eq i32 %t, 0
266  %t3 = and i32 %arg, 1
267  %t4 = select i1 %t2, i32 %t3, i32 1
268  ret i32 %t4
269}
270
271define <2 x i32> @f_var1_vec(<2 x i32> %arg, <2 x i32> %arg1) {
272; CHECK-LABEL: @f_var1_vec(
273; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[ARG1:%.*]], splat (i32 1)
274; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[ARG:%.*]], [[TMP1]]
275; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
276; CHECK-NEXT:    [[T4:%.*]] = zext <2 x i1> [[TMP3]] to <2 x i32>
277; CHECK-NEXT:    ret <2 x i32> [[T4]]
278;
279  %t = and <2 x i32> %arg, %arg1
280  %t2 = icmp eq <2 x i32> %t, zeroinitializer
281  %t3 = and <2 x i32> %arg, <i32 1, i32 1>
282  %t4 = select <2 x i1> %t2, <2 x i32> %t3, <2 x i32> <i32 1, i32 1>
283  ret <2 x i32> %t4
284}
285
286define <3 x i32> @f_var1_vec_poison(<3 x i32> %arg, <3 x i32> %arg1) {
287; CHECK-LABEL: @f_var1_vec_poison(
288; CHECK-NEXT:    [[TMP1:%.*]] = or <3 x i32> [[ARG1:%.*]], splat (i32 1)
289; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[ARG:%.*]], [[TMP1]]
290; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
291; CHECK-NEXT:    [[T4:%.*]] = zext <3 x i1> [[TMP3]] to <3 x i32>
292; CHECK-NEXT:    ret <3 x i32> [[T4]]
293;
294  %t = and <3 x i32> %arg, %arg1
295  %t2 = icmp eq <3 x i32> %t, <i32 0, i32 poison, i32 0>
296  %t3 = and <3 x i32> %arg, <i32 1, i32 poison, i32 1>
297  %t4 = select <3 x i1> %t2, <3 x i32> %t3, <3 x i32> <i32 1, i32 poison, i32 1>
298  ret <3 x i32> %t4
299}
300
301; ============================================================================ ;
302; Shift can't be a variable in general.
303; ============================================================================ ;
304
305define i32 @f_var2(i32 %arg, i32 %arg1) {
306; CHECK-LABEL: @f_var2(
307; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 1
308; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T]], 0
309; CHECK-NEXT:    [[T3:%.*]] = lshr i32 [[ARG]], [[ARG1:%.*]]
310; CHECK-NEXT:    [[T4:%.*]] = and i32 [[T3]], 1
311; CHECK-NEXT:    [[T5:%.*]] = select i1 [[T2]], i32 [[T4]], i32 1
312; CHECK-NEXT:    ret i32 [[T5]]
313;
314  %t = and i32 %arg, 1
315  %t2 = icmp eq i32 %t, 0
316  %t3 = lshr i32 %arg, %arg1
317  %t4 = and i32 %t3, 1
318  %t5 = select i1 %t2, i32 %t4, i32 1
319  ret i32 %t5
320}
321
322define <2 x i32> @f_var2_splatvec(<2 x i32> %arg, <2 x i32> %arg1) {
323; CHECK-LABEL: @f_var2_splatvec(
324; CHECK-NEXT:    [[T:%.*]] = and <2 x i32> [[ARG:%.*]], splat (i32 1)
325; CHECK-NEXT:    [[T2:%.*]] = icmp eq <2 x i32> [[T]], zeroinitializer
326; CHECK-NEXT:    [[T3:%.*]] = lshr <2 x i32> [[ARG]], [[ARG1:%.*]]
327; CHECK-NEXT:    [[T4:%.*]] = and <2 x i32> [[T3]], splat (i32 1)
328; CHECK-NEXT:    [[T5:%.*]] = select <2 x i1> [[T2]], <2 x i32> [[T4]], <2 x i32> splat (i32 1)
329; CHECK-NEXT:    ret <2 x i32> [[T5]]
330;
331  %t = and <2 x i32> %arg, <i32 1, i32 1>
332  %t2 = icmp eq <2 x i32> %t, zeroinitializer
333  %t3 = lshr <2 x i32> %arg, %arg1
334  %t4 = and <2 x i32> %t3, <i32 1, i32 1>
335  %t5 = select <2 x i1> %t2, <2 x i32> %t4, <2 x i32> <i32 1, i32 1>
336  ret <2 x i32> %t5
337}
338
339define <2 x i32> @f_var2_vec(<2 x i32> %arg, <2 x i32> %arg1) {
340; CHECK-LABEL: @f_var2_vec(
341; CHECK-NEXT:    [[T:%.*]] = and <2 x i32> [[ARG:%.*]], <i32 2, i32 1>
342; CHECK-NEXT:    [[T2:%.*]] = icmp eq <2 x i32> [[T]], zeroinitializer
343; CHECK-NEXT:    [[T3:%.*]] = lshr <2 x i32> [[ARG]], [[ARG1:%.*]]
344; CHECK-NEXT:    [[T4:%.*]] = and <2 x i32> [[T3]], splat (i32 1)
345; CHECK-NEXT:    [[T5:%.*]] = select <2 x i1> [[T2]], <2 x i32> [[T4]], <2 x i32> splat (i32 1)
346; CHECK-NEXT:    ret <2 x i32> [[T5]]
347;
348  %t = and <2 x i32> %arg, <i32 2, i32 1>; mask is not splat
349  %t2 = icmp eq <2 x i32> %t, zeroinitializer
350  %t3 = lshr <2 x i32> %arg, %arg1
351  %t4 = and <2 x i32> %t3, <i32 1, i32 1>
352  %t5 = select <2 x i1> %t2, <2 x i32> %t4, <2 x i32> <i32 1, i32 1>
353  ret <2 x i32> %t5
354}
355
356define <3 x i32> @f_var2_vec_poison(<3 x i32> %arg, <3 x i32> %arg1) {
357; CHECK-LABEL: @f_var2_vec_poison(
358; CHECK-NEXT:    [[T:%.*]] = and <3 x i32> [[ARG:%.*]], <i32 1, i32 poison, i32 1>
359; CHECK-NEXT:    [[T2:%.*]] = icmp eq <3 x i32> [[T]], <i32 0, i32 poison, i32 0>
360; CHECK-NEXT:    [[T3:%.*]] = lshr <3 x i32> [[ARG]], [[ARG1:%.*]]
361; CHECK-NEXT:    [[T4:%.*]] = and <3 x i32> [[T3]], <i32 1, i32 poison, i32 1>
362; CHECK-NEXT:    [[T5:%.*]] = select <3 x i1> [[T2]], <3 x i32> [[T4]], <3 x i32> <i32 1, i32 poison, i32 1>
363; CHECK-NEXT:    ret <3 x i32> [[T5]]
364;
365  %t = and <3 x i32> %arg, <i32 1, i32 poison, i32 1>
366  %t2 = icmp eq <3 x i32> %t, <i32 0, i32 poison, i32 0>
367  %t3 = lshr <3 x i32> %arg, %arg1
368  %t4 = and <3 x i32> %t3, <i32 1, i32 poison, i32 1>
369  %t5 = select <3 x i1> %t2, <3 x i32> %t4, <3 x i32> <i32 1, i32 poison, i32 1>
370  ret <3 x i32> %t5
371}
372
373; ============================================================================ ;
374; The worst case: both Mask and Shift are variables
375; ============================================================================ ;
376
377define i32 @f_var3(i32 %arg, i32 %arg1, i32 %arg2) {
378; CHECK-LABEL: @f_var3(
379; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], [[ARG1:%.*]]
380; CHECK-NEXT:    [[T3:%.*]] = icmp eq i32 [[T]], 0
381; CHECK-NEXT:    [[T4:%.*]] = lshr i32 [[ARG]], [[ARG2:%.*]]
382; CHECK-NEXT:    [[T5:%.*]] = and i32 [[T4]], 1
383; CHECK-NEXT:    [[T6:%.*]] = select i1 [[T3]], i32 [[T5]], i32 1
384; CHECK-NEXT:    ret i32 [[T6]]
385;
386  %t = and i32 %arg, %arg1
387  %t3 = icmp eq i32 %t, 0
388  %t4 = lshr i32 %arg, %arg2
389  %t5 = and i32 %t4, 1
390  %t6 = select i1 %t3, i32 %t5, i32 1
391  ret i32 %t6
392}
393
394; Should be exactly as the previous one
395define i32 @f_var3_commutative_and(i32 %arg, i32 %arg1, i32 %arg2) {
396; CHECK-LABEL: @f_var3_commutative_and(
397; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG1:%.*]], [[ARG:%.*]]
398; CHECK-NEXT:    [[T3:%.*]] = icmp eq i32 [[T]], 0
399; CHECK-NEXT:    [[T4:%.*]] = lshr i32 [[ARG]], [[ARG2:%.*]]
400; CHECK-NEXT:    [[T5:%.*]] = and i32 [[T4]], 1
401; CHECK-NEXT:    [[T6:%.*]] = select i1 [[T3]], i32 [[T5]], i32 1
402; CHECK-NEXT:    ret i32 [[T6]]
403;
404  %t = and i32 %arg1, %arg ; in different order
405  %t3 = icmp eq i32 %t, 0
406  %t4 = lshr i32 %arg, %arg2
407  %t5 = and i32 %t4, 1
408  %t6 = select i1 %t3, i32 %t5, i32 1
409  ret i32 %t6
410}
411
412define <2 x i32> @f_var3_splatvec(<2 x i32> %arg, <2 x i32> %arg1, <2 x i32> %arg2) {
413; CHECK-LABEL: @f_var3_splatvec(
414; CHECK-NEXT:    [[T:%.*]] = and <2 x i32> [[ARG:%.*]], [[ARG1:%.*]]
415; CHECK-NEXT:    [[T3:%.*]] = icmp eq <2 x i32> [[T]], zeroinitializer
416; CHECK-NEXT:    [[T4:%.*]] = lshr <2 x i32> [[ARG]], [[ARG2:%.*]]
417; CHECK-NEXT:    [[T5:%.*]] = and <2 x i32> [[T4]], splat (i32 1)
418; CHECK-NEXT:    [[T6:%.*]] = select <2 x i1> [[T3]], <2 x i32> [[T5]], <2 x i32> splat (i32 1)
419; CHECK-NEXT:    ret <2 x i32> [[T6]]
420;
421  %t = and <2 x i32> %arg, %arg1
422  %t3 = icmp eq <2 x i32> %t, zeroinitializer
423  %t4 = lshr <2 x i32> %arg, %arg2
424  %t5 = and <2 x i32> %t4, <i32 1, i32 1>
425  %t6 = select <2 x i1> %t3, <2 x i32> %t5, <2 x i32> <i32 1, i32 1>
426  ret <2 x i32> %t6
427}
428
429define <3 x i32> @f_var3_vec_poison(<3 x i32> %arg, <3 x i32> %arg1, <3 x i32> %arg2) {
430; CHECK-LABEL: @f_var3_vec_poison(
431; CHECK-NEXT:    [[T:%.*]] = and <3 x i32> [[ARG:%.*]], [[ARG1:%.*]]
432; CHECK-NEXT:    [[T3:%.*]] = icmp eq <3 x i32> [[T]], <i32 0, i32 poison, i32 0>
433; CHECK-NEXT:    [[T4:%.*]] = lshr <3 x i32> [[ARG]], [[ARG2:%.*]]
434; CHECK-NEXT:    [[T5:%.*]] = and <3 x i32> [[T4]], <i32 1, i32 poison, i32 1>
435; CHECK-NEXT:    [[T6:%.*]] = select <3 x i1> [[T3]], <3 x i32> [[T5]], <3 x i32> <i32 1, i32 poison, i32 1>
436; CHECK-NEXT:    ret <3 x i32> [[T6]]
437;
438  %t = and <3 x i32> %arg, %arg1
439  %t3 = icmp eq <3 x i32> %t, <i32 0, i32 poison, i32 0>
440  %t4 = lshr <3 x i32> %arg, %arg2
441  %t5 = and <3 x i32> %t4, <i32 1, i32 poison, i32 1>
442  %t6 = select <3 x i1> %t3, <3 x i32> %t5, <3 x i32> <i32 1, i32 poison, i32 1>
443  ret <3 x i32> %t6
444}
445
446; ============================================================================ ;
447; Negative tests. Should not be folded.
448; ============================================================================ ;
449
450; One use only.
451
452declare void @use32(i32)
453
454declare void @use1(i1)
455
456define i32 @n_var0_oneuse(i32 %arg, i32 %arg1, i32 %arg2) {
457; CHECK-LABEL: @n_var0_oneuse(
458; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], [[ARG1:%.*]]
459; CHECK-NEXT:    [[T3:%.*]] = icmp eq i32 [[T]], 0
460; CHECK-NEXT:    [[T4:%.*]] = lshr i32 [[ARG]], [[ARG2:%.*]]
461; CHECK-NEXT:    [[T5:%.*]] = and i32 [[T4]], 1
462; CHECK-NEXT:    [[T6:%.*]] = select i1 [[T3]], i32 [[T5]], i32 1
463; CHECK-NEXT:    call void @use32(i32 [[T]])
464; CHECK-NEXT:    call void @use1(i1 [[T3]])
465; CHECK-NEXT:    call void @use32(i32 [[T4]])
466; CHECK-NEXT:    call void @use32(i32 [[T5]])
467; CHECK-NEXT:    ret i32 [[T6]]
468;
469  %t = and i32 %arg, %arg1
470  %t3 = icmp eq i32 %t, 0
471  %t4 = lshr i32 %arg, %arg2
472  %t5 = and i32 %t4, 1
473  %t6 = select i1 %t3, i32 %t5, i32 1
474  call void @use32(i32 %t)
475  call void @use1(i1 %t3)
476  call void @use32(i32 %t4)
477  call void @use32(i32 %t5)
478  ret i32 %t6
479}
480
481define i32 @n_var1_oneuse(i32 %arg, i32 %arg1) {
482; CHECK-LABEL: @n_var1_oneuse(
483; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], [[ARG1:%.*]]
484; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T]], 0
485; CHECK-NEXT:    [[T3:%.*]] = and i32 [[ARG]], 1
486; CHECK-NEXT:    [[T4:%.*]] = select i1 [[T2]], i32 [[T3]], i32 1
487; CHECK-NEXT:    call void @use32(i32 [[T]])
488; CHECK-NEXT:    call void @use1(i1 [[T2]])
489; CHECK-NEXT:    call void @use32(i32 [[T3]])
490; CHECK-NEXT:    ret i32 [[T4]]
491;
492  %t = and i32 %arg, %arg1
493  %t2 = icmp eq i32 %t, 0
494  %t3 = and i32 %arg, 1
495  %t4 = select i1 %t2, i32 %t3, i32 1
496  call void @use32(i32 %t)
497  call void @use1(i1 %t2)
498  call void @use32(i32 %t3)
499  ret i32 %t4
500}
501
502; Different variables are used
503
504define i32 @n0(i32 %arg, i32 %arg1) {
505; CHECK-LABEL: @n0(
506; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 1
507; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T]], 0
508; CHECK-NEXT:    [[T3:%.*]] = lshr i32 [[ARG1:%.*]], 1
509; CHECK-NEXT:    [[T4:%.*]] = and i32 [[T3]], 1
510; CHECK-NEXT:    [[T5:%.*]] = select i1 [[T2]], i32 [[T4]], i32 1
511; CHECK-NEXT:    ret i32 [[T5]]
512;
513  %t = and i32 %arg, 1
514  %t2 = icmp eq i32 %t, 0
515  %t3 = lshr i32 %arg1, 1 ; works on %arg1 instead of %arg
516  %t4 = and i32 %t3, 1
517  %t5 = select i1 %t2, i32 %t4, i32 1
518  ret i32 %t5
519}
520
521define i32 @n1(i32 %arg, i32 %arg1) {
522; CHECK-LABEL: @n1(
523; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 2
524; CHECK-NEXT:    [[T2:%.*]] = icmp eq i32 [[T]], 0
525; CHECK-NEXT:    [[T3:%.*]] = and i32 [[ARG1:%.*]], 1
526; CHECK-NEXT:    [[T4:%.*]] = select i1 [[T2]], i32 [[T3]], i32 1
527; CHECK-NEXT:    ret i32 [[T4]]
528;
529  %t = and i32 %arg, 2
530  %t2 = icmp eq i32 %t, 0
531  %t3 = and i32 %arg1, 1 ; works on %arg1 instead of %arg
532  %t4 = select i1 %t2, i32 %t3, i32 1
533  ret i32 %t4
534}
535
536; False-value is not 1
537
538define i32 @n2(i32 %arg) {
539; CHECK-LABEL: @n2(
540; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 1
541; CHECK-NEXT:    [[T1:%.*]] = icmp eq i32 [[T]], 0
542; CHECK-NEXT:    [[T2:%.*]] = lshr i32 [[ARG]], 2
543; CHECK-NEXT:    [[T3:%.*]] = and i32 [[T2]], 1
544; CHECK-NEXT:    [[T4:%.*]] = select i1 [[T1]], i32 [[T3]], i32 0
545; CHECK-NEXT:    ret i32 [[T4]]
546;
547  %t = and i32 %arg, 1
548  %t1 = icmp eq i32 %t, 0
549  %t2 = lshr i32 %arg, 2
550  %t3 = and i32 %t2, 1
551  %t4 = select i1 %t1, i32 %t3, i32 0 ; 0 instead of 1
552  ret i32 %t4
553}
554
555define i32 @n3(i32 %arg) {
556; CHECK-LABEL: @n3(
557; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 2
558; CHECK-NEXT:    [[T1:%.*]] = icmp eq i32 [[T]], 0
559; CHECK-NEXT:    [[T2:%.*]] = and i32 [[ARG]], 1
560; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T1]], i32 [[T2]], i32 0
561; CHECK-NEXT:    ret i32 [[T3]]
562;
563  %t = and i32 %arg, 2
564  %t1 = icmp eq i32 %t, 0
565  %t2 = and i32 %arg, 1
566  %t3 = select i1 %t1, i32 %t2, i32 0 ; 0 instead of 1
567  ret i32 %t3
568}
569
570; Mask of second and is not one
571
572define i32 @n4(i32 %arg) {
573; CHECK-LABEL: @n4(
574; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 1
575; CHECK-NEXT:    [[T1:%.*]] = icmp eq i32 [[T]], 0
576; CHECK-NEXT:    [[T2:%.*]] = lshr i32 [[ARG]], 2
577; CHECK-NEXT:    [[T3:%.*]] = and i32 [[T2]], 2
578; CHECK-NEXT:    [[T4:%.*]] = select i1 [[T1]], i32 [[T3]], i32 1
579; CHECK-NEXT:    ret i32 [[T4]]
580;
581  %t = and i32 %arg, 1
582  %t1 = icmp eq i32 %t, 0
583  %t2 = lshr i32 %arg, 2
584  %t3 = and i32 %t2, 2 ; 2 instead of 1
585  %t4 = select i1 %t1, i32 %t3, i32 1
586  ret i32 %t4
587}
588
589define i32 @n5(i32 %arg) {
590; CHECK-LABEL: @n5(
591; CHECK-NEXT:    [[T:%.*]] = lshr i32 [[ARG:%.*]], 1
592; CHECK-NEXT:    [[T_LOBIT:%.*]] = and i32 [[T]], 1
593; CHECK-NEXT:    ret i32 [[T_LOBIT]]
594;
595  %t = and i32 %arg, 2
596  %t1 = icmp eq i32 %t, 0
597  %t2 = and i32 %arg, 2 ; 2 instead of 1
598  %t3 = select i1 %t1, i32 %t2, i32 1
599  ret i32 %t3
600}
601
602; Wrong icmp pred
603
604define i32 @n6(i32 %arg) {
605; CHECK-LABEL: @n6(
606; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 1
607; CHECK-NEXT:    [[T1_NOT:%.*]] = icmp eq i32 [[T]], 0
608; CHECK-NEXT:    [[T2:%.*]] = lshr i32 [[ARG]], 2
609; CHECK-NEXT:    [[T3:%.*]] = and i32 [[T2]], 1
610; CHECK-NEXT:    [[T4:%.*]] = select i1 [[T1_NOT]], i32 1, i32 [[T3]]
611; CHECK-NEXT:    ret i32 [[T4]]
612;
613  %t = and i32 %arg, 1
614  %t1 = icmp ne i32 %t, 0 ; ne, not eq
615  %t2 = lshr i32 %arg, 2
616  %t3 = and i32 %t2, 1
617  %t4 = select i1 %t1, i32 %t3, i32 1
618  ret i32 %t4
619}
620
621define i32 @n7(i32 %arg) {
622; CHECK-LABEL: @n7(
623; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 2
624; CHECK-NEXT:    [[T1_NOT:%.*]] = icmp eq i32 [[T]], 0
625; CHECK-NEXT:    [[T2:%.*]] = and i32 [[ARG]], 1
626; CHECK-NEXT:    [[T3:%.*]] = select i1 [[T1_NOT]], i32 1, i32 [[T2]]
627; CHECK-NEXT:    ret i32 [[T3]]
628;
629  %t = and i32 %arg, 2
630  %t1 = icmp ne i32 %t, 0 ; ne, not eq
631  %t2 = and i32 %arg, 1
632  %t3 = select i1 %t1, i32 %t2, i32 1
633  ret i32 %t3
634}
635
636; icmp second operand is not zero
637
638define i32 @n8(i32 %arg) {
639; CHECK-LABEL: @n8(
640; CHECK-NEXT:    [[T:%.*]] = and i32 [[ARG:%.*]], 1
641; CHECK-NEXT:    [[T1_NOT:%.*]] = icmp eq i32 [[T]], 0
642; CHECK-NEXT:    [[T2:%.*]] = lshr i32 [[ARG]], 2
643; CHECK-NEXT:    [[T3:%.*]] = and i32 [[T2]], 1
644; CHECK-NEXT:    [[T4:%.*]] = select i1 [[T1_NOT]], i32 1, i32 [[T3]]
645; CHECK-NEXT:    ret i32 [[T4]]
646;
647  %t = and i32 %arg, 1
648  %t1 = icmp eq i32 %t, 1
649  %t2 = lshr i32 %arg, 2
650  %t3 = and i32 %t2, 1
651  %t4 = select i1 %t1, i32 %t3, i32 1
652  ret i32 %t4
653}
654