[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / InstCombine / select-of-bittest.ll
blobd9bef00b2f78cfd01e80db7d6c66219e8d5c8afb
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 ; https://bugs.llvm.org/show_bug.cgi?id=36950
6 ; These all should be just and+icmp, there should be no select.
8 define 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]]
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
23 define <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]]
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
38 define <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]]
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
53 define <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]]
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
68 define <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]]
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
83 define <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]]
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
98 define 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]]
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
112 define <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]]
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
126 define <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]]
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
140 define <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]]
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
154 ; ============================================================================ ;
155 ; Mask can be a variable, too.
156 ; ============================================================================ ;
158 define 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]]
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
174 ; Should be exactly as the previous one
175 define 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]]
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
191 define <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]]
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
207 define <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]]
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
223 define <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]]
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
239 define 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]]
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
254 ; Should be exactly as the previous one
255 define 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]]
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
270 define <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]]
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
285 define <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]]
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
300 ; ============================================================================ ;
301 ; Shift can be a variable, too.
302 ; ============================================================================ ;
304 define 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]]
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
321 define <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]]
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
338 define <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]]
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
355 define <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]]
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
372 ; ============================================================================ ;
373 ; The worst case: both Mask and Shift are variables
374 ; ============================================================================ ;
376 define 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]]
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
393 ; Should be exactly as the previous one
394 define 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]]
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
411 define <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]]
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
428 define <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]]
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
445 ; ============================================================================ ;
446 ; Negative tests. Should not be folded.
447 ; ============================================================================ ;
449 ; One use only.
451 declare void @use32(i32)
453 declare void @use1(i1)
455 define 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]]
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
480 define 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]]
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
501 ; Different variables are used
503 define 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]]
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
520 define 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]]
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
535 ; False-value is not 1
537 define 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]]
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
554 define 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]]
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
569 ; Mask of second and is not one
571 define 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]]
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
588 define 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]]
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
603 ; Wrong icmp pred
605 define 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]]
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
622 define 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]]
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
637 ; icmp second operand is not zero
639 define 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]]
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