[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstCombine / select-of-bittest.ll
blobc85bcba82e97922ff0d215a5ac1e3aa236b1c171
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 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]]
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
99 define 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]]
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
113 define <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]]
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
127 define <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]]
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
141 define <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]]
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
155 ; ============================================================================ ;
156 ; Mask can be a variable, too.
157 ; ============================================================================ ;
159 define 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]]
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
175 ; Should be exactly as the previous one
176 define 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]]
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
192 define <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]]
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
208 define <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]]
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
224 define <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]]
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
241 define 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]]
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
256 ; Should be exactly as the previous one
257 define 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]]
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
272 define <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]]
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
287 define <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]]
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
302 ; ============================================================================ ;
303 ; Shift can be a variable, too.
304 ; ============================================================================ ;
306 define 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]]
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
323 define <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]]
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
340 define <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]]
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
357 define <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]]
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
374 ; ============================================================================ ;
375 ; The worst case: both Mask and Shift are variables
376 ; ============================================================================ ;
378 define 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]]
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
395 ; Should be exactly as the previous one
396 define 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]]
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
413 define <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]]
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
430 define <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]]
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
447 ; ============================================================================ ;
448 ; Negative tests. Should not be folded.
449 ; ============================================================================ ;
451 ; One use only.
453 declare void @use32(i32)
455 declare void @use1(i1)
457 define 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]]
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
482 define 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]]
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
503 ; Different variables are used
505 define 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]]
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
522 define 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]]
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
537 ; False-value is not 1
539 define 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]]
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
556 define 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]]
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
571 ; Mask of second and is not one
573 define 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]]
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
590 define 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]]
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
605 ; Wrong icmp pred
607 define 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]]
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
624 define 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]]
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
639 ; icmp second operand is not zero
641 define 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]]
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