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