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