Revert "[InstCombine] Support gep nuw in icmp folds" (#118698)
[llvm-project.git] / llvm / test / Transforms / InstCombine / shift-amount-reassociation-in-bittest.ll
blobe95955da1b8728f96be0ffcc6801c97ae90b5936
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 ; Given pattern:
5 ;   icmp eq/ne (and ((x shift Q), (y oppositeshift K))), 0
6 ; we should move shifts to the same hand of 'and', i.e. e.g. rewrite as
7 ;   icmp eq/ne (and (((x shift Q) shift K), y)), 0
8 ; We are only interested in opposite logical shifts here.
10 ; Basic scalar test with constants
12 define i1 @t0_const_lshr_shl_ne(i32 %x, i32 %y) {
13 ; CHECK-LABEL: @t0_const_lshr_shl_ne(
14 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
15 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]
16 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0
17 ; CHECK-NEXT:    ret i1 [[T3]]
19   %t0 = lshr i32 %x, 1
20   %t1 = shl i32 %y, 1
21   %t2 = and i32 %t1, %t0
22   %t3 = icmp ne i32 %t2, 0
23   ret i1 %t3
25 define i1 @t1_const_shl_lshr_ne(i32 %x, i32 %y) {
26 ; CHECK-LABEL: @t1_const_shl_lshr_ne(
27 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], 2
28 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[X:%.*]]
29 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0
30 ; CHECK-NEXT:    ret i1 [[T3]]
32   %t0 = shl i32 %x, 1
33   %t1 = lshr i32 %y, 1
34   %t2 = and i32 %t1, %t0
35   %t3 = icmp ne i32 %t2, 0
36   ret i1 %t3
39 ; We are ok with 'eq' predicate too.
40 define i1 @t2_const_lshr_shl_eq(i32 %x, i32 %y) {
41 ; CHECK-LABEL: @t2_const_lshr_shl_eq(
42 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
43 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]
44 ; CHECK-NEXT:    [[T3:%.*]] = icmp eq i32 [[TMP2]], 0
45 ; CHECK-NEXT:    ret i1 [[T3]]
47   %t0 = lshr i32 %x, 1
48   %t1 = shl i32 %y, 1
49   %t2 = and i32 %t1, %t0
50   %t3 = icmp eq i32 %t2, 0
51   ret i1 %t3
54 ; Basic scalar test with constants after folding
56 define i1 @t3_const_after_fold_lshr_shl_ne(i32 %x, i32 %y, i32 %len) {
57 ; CHECK-LABEL: @t3_const_after_fold_lshr_shl_ne(
58 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 31
59 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]
60 ; CHECK-NEXT:    [[T5:%.*]] = icmp ne i32 [[TMP2]], 0
61 ; CHECK-NEXT:    ret i1 [[T5]]
63   %t0 = sub i32 32, %len
64   %t1 = lshr i32 %x, %t0
65   %t2 = add i32 %len, -1
66   %t3 = shl i32 %y, %t2
67   %t4 = and i32 %t1, %t3
68   %t5 = icmp ne i32 %t4, 0
69   ret i1 %t5
71 define i1 @t4_const_after_fold_lshr_shl_ne(i32 %x, i32 %y, i32 %len) {
72 ; CHECK-LABEL: @t4_const_after_fold_lshr_shl_ne(
73 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[Y:%.*]], 31
74 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[X:%.*]]
75 ; CHECK-NEXT:    [[T5:%.*]] = icmp ne i32 [[TMP2]], 0
76 ; CHECK-NEXT:    ret i1 [[T5]]
78   %t0 = sub i32 32, %len
79   %t1 = shl i32 %x, %t0
80   %t2 = add i32 %len, -1
81   %t3 = lshr i32 %y, %t2
82   %t4 = and i32 %t1, %t3
83   %t5 = icmp ne i32 %t4, 0
84   ret i1 %t5
87 ; Completely variable shift amounts
89 define i1 @t5_const_lshr_shl_ne(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
90 ; CHECK-LABEL: @t5_const_lshr_shl_ne(
91 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]
92 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]
93 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]
94 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0
95 ; CHECK-NEXT:    ret i1 [[T3]]
97   %t0 = lshr i32 %x, %shamt0
98   %t1 = shl i32 %y, %shamt1
99   %t2 = and i32 %t1, %t0
100   %t3 = icmp ne i32 %t2, 0
101   ret i1 %t3
103 define i1 @t6_const_shl_lshr_ne(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
104 ; CHECK-LABEL: @t6_const_shl_lshr_ne(
105 ; CHECK-NEXT:    [[T0:%.*]] = shl i32 [[X:%.*]], [[SHAMT0:%.*]]
106 ; CHECK-NEXT:    [[T1:%.*]] = lshr i32 [[Y:%.*]], [[SHAMT1:%.*]]
107 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]
108 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0
109 ; CHECK-NEXT:    ret i1 [[T3]]
111   %t0 = shl i32 %x, %shamt0
112   %t1 = lshr i32 %y, %shamt1
113   %t2 = and i32 %t1, %t0
114   %t3 = icmp ne i32 %t2, 0
115   ret i1 %t3
118 ; Very basic vector tests
120 define <2 x i1> @t7_const_lshr_shl_ne_vec_splat(<2 x i32> %x, <2 x i32> %y) {
121 ; CHECK-LABEL: @t7_const_lshr_shl_ne_vec_splat(
122 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], splat (i32 2)
123 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[Y:%.*]]
124 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
125 ; CHECK-NEXT:    ret <2 x i1> [[T3]]
127   %t0 = lshr <2 x i32> %x, <i32 1, i32 1>
128   %t1 = shl <2 x i32> %y, <i32 1, i32 1>
129   %t2 = and <2 x i32> %t1, %t0
130   %t3 = icmp ne <2 x i32> %t2, <i32 0, i32 0>
131   ret <2 x i1> %t3
133 define <2 x i1> @t8_const_lshr_shl_ne_vec_nonsplat(<2 x i32> %x, <2 x i32> %y) {
134 ; CHECK-LABEL: @t8_const_lshr_shl_ne_vec_nonsplat(
135 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 4, i32 6>
136 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[Y:%.*]]
137 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
138 ; CHECK-NEXT:    ret <2 x i1> [[T3]]
140   %t0 = lshr <2 x i32> %x, <i32 1, i32 2>
141   %t1 = shl <2 x i32> %y, <i32 3, i32 4>
142   %t2 = and <2 x i32> %t1, %t0
143   %t3 = icmp ne <2 x i32> %t2, <i32 0, i32 0>
144   ret <2 x i1> %t3
146 define <3 x i1> @t9_const_lshr_shl_ne_vec_poison0(<3 x i32> %x, <3 x i32> %y) {
147 ; CHECK-LABEL: @t9_const_lshr_shl_ne_vec_poison0(
148 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 poison, i32 2>
149 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
150 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
151 ; CHECK-NEXT:    ret <3 x i1> [[T3]]
153   %t0 = lshr <3 x i32> %x, <i32 1, i32 poison, i32 1>
154   %t1 = shl <3 x i32> %y, <i32 1, i32 1, i32 1>
155   %t2 = and <3 x i32> %t1, %t0
156   %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 0, i32 0>
157   ret <3 x i1> %t3
159 define <3 x i1> @t10_const_lshr_shl_ne_vec_poison1(<3 x i32> %x, <3 x i32> %y) {
160 ; CHECK-LABEL: @t10_const_lshr_shl_ne_vec_poison1(
161 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 poison, i32 2>
162 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
163 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
164 ; CHECK-NEXT:    ret <3 x i1> [[T3]]
166   %t0 = lshr <3 x i32> %x, <i32 1, i32 1, i32 1>
167   %t1 = shl <3 x i32> %y, <i32 1, i32 poison, i32 1>
168   %t2 = and <3 x i32> %t1, %t0
169   %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 0, i32 0>
170   ret <3 x i1> %t3
172 define <3 x i1> @t11_const_lshr_shl_ne_vec_poison2(<3 x i32> %x, <3 x i32> %y) {
173 ; CHECK-LABEL: @t11_const_lshr_shl_ne_vec_poison2(
174 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], splat (i32 2)
175 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
176 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
177 ; CHECK-NEXT:    ret <3 x i1> [[T3]]
179   %t0 = lshr <3 x i32> %x, <i32 1, i32 1, i32 1>
180   %t1 = shl <3 x i32> %y, <i32 1, i32 1, i32 1>
181   %t2 = and <3 x i32> %t1, %t0
182   %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 poison, i32 0>
183   ret <3 x i1> %t3
185 define <3 x i1> @t12_const_lshr_shl_ne_vec_poison3(<3 x i32> %x, <3 x i32> %y) {
186 ; CHECK-LABEL: @t12_const_lshr_shl_ne_vec_poison3(
187 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 poison, i32 2>
188 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
189 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
190 ; CHECK-NEXT:    ret <3 x i1> [[T3]]
192   %t0 = lshr <3 x i32> %x, <i32 1, i32 poison, i32 1>
193   %t1 = shl <3 x i32> %y, <i32 1, i32 poison, i32 1>
194   %t2 = and <3 x i32> %t1, %t0
195   %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 0, i32 0>
196   ret <3 x i1> %t3
198 define <3 x i1> @t13_const_lshr_shl_ne_vec_poison4(<3 x i32> %x, <3 x i32> %y) {
199 ; CHECK-LABEL: @t13_const_lshr_shl_ne_vec_poison4(
200 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 poison, i32 2>
201 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
202 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
203 ; CHECK-NEXT:    ret <3 x i1> [[T3]]
205   %t0 = lshr <3 x i32> %x, <i32 1, i32 1, i32 1>
206   %t1 = shl <3 x i32> %y, <i32 1, i32 poison, i32 1>
207   %t2 = and <3 x i32> %t1, %t0
208   %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 poison, i32 0>
209   ret <3 x i1> %t3
211 define <3 x i1> @t14_const_lshr_shl_ne_vec_poison5(<3 x i32> %x, <3 x i32> %y) {
212 ; CHECK-LABEL: @t14_const_lshr_shl_ne_vec_poison5(
213 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 poison, i32 2>
214 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
215 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
216 ; CHECK-NEXT:    ret <3 x i1> [[T3]]
218   %t0 = lshr <3 x i32> %x, <i32 1, i32 poison, i32 1>
219   %t1 = shl <3 x i32> %y, <i32 1, i32 1, i32 1>
220   %t2 = and <3 x i32> %t1, %t0
221   %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 poison, i32 0>
222   ret <3 x i1> %t3
224 define <3 x i1> @t15_const_lshr_shl_ne_vec_poison6(<3 x i32> %x, <3 x i32> %y) {
225 ; CHECK-LABEL: @t15_const_lshr_shl_ne_vec_poison6(
226 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 poison, i32 2>
227 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
228 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
229 ; CHECK-NEXT:    ret <3 x i1> [[T3]]
231   %t0 = lshr <3 x i32> %x, <i32 1, i32 poison, i32 1>
232   %t1 = shl <3 x i32> %y, <i32 1, i32 poison, i32 1>
233   %t2 = and <3 x i32> %t1, %t0
234   %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 poison, i32 0>
235   ret <3 x i1> %t3
238 ; Commutativity tests
240 declare i32 @gen32()
242 define i1 @t16_commutativity0(i32 %x) {
243 ; CHECK-LABEL: @t16_commutativity0(
244 ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
245 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
246 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]
247 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0
248 ; CHECK-NEXT:    ret i1 [[T3]]
250   %y = call i32 @gen32()
251   %t0 = lshr i32 %x, 1
252   %t1 = shl i32 %y, 1
253   %t2 = and i32 %t1, %t0
254   %t3 = icmp ne i32 %t2, 0
255   ret i1 %t3
258 define i1 @t17_commutativity1(i32 %y) {
259 ; CHECK-LABEL: @t17_commutativity1(
260 ; CHECK-NEXT:    [[X:%.*]] = call i32 @gen32()
261 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X]], 2
262 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]
263 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0
264 ; CHECK-NEXT:    ret i1 [[T3]]
266   %x = call i32 @gen32()
267   %t0 = lshr i32 %x, 1
268   %t1 = shl i32 %y, 1
269   %t2 = and i32 %t0, %t1 ; "swapped"
270   %t3 = icmp ne i32 %t2, 0
271   ret i1 %t3
274 ; One-use tests
276 declare void @use32(i32)
278 define i1 @t18_const_oneuse0(i32 %x, i32 %y) {
279 ; CHECK-LABEL: @t18_const_oneuse0(
280 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], 1
281 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
282 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X]], 2
283 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]
284 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0
285 ; CHECK-NEXT:    ret i1 [[T3]]
287   %t0 = lshr i32 %x, 1
288   call void @use32(i32 %t0)
289   %t1 = shl i32 %y, 1
290   %t2 = and i32 %t1, %t0
291   %t3 = icmp ne i32 %t2, 0
292   ret i1 %t3
294 define i1 @t19_const_oneuse1(i32 %x, i32 %y) {
295 ; CHECK-LABEL: @t19_const_oneuse1(
296 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], 1
297 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
298 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
299 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]
300 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0
301 ; CHECK-NEXT:    ret i1 [[T3]]
303   %t0 = lshr i32 %x, 1
304   %t1 = shl i32 %y, 1
305   call void @use32(i32 %t1)
306   %t2 = and i32 %t1, %t0
307   %t3 = icmp ne i32 %t2, 0
308   ret i1 %t3
310 define i1 @t20_const_oneuse2(i32 %x, i32 %y) {
311 ; CHECK-LABEL: @t20_const_oneuse2(
312 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], 1
313 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], 1
314 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]
315 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
316 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0
317 ; CHECK-NEXT:    ret i1 [[T3]]
319   %t0 = lshr i32 %x, 1
320   %t1 = shl i32 %y, 1
321   %t2 = and i32 %t1, %t0
322   call void @use32(i32 %t2)
323   %t3 = icmp ne i32 %t2, 0
324   ret i1 %t3
326 define i1 @t21_const_oneuse3(i32 %x, i32 %y) {
327 ; CHECK-LABEL: @t21_const_oneuse3(
328 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], 1
329 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
330 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], 1
331 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
332 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]
333 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0
334 ; CHECK-NEXT:    ret i1 [[T3]]
336   %t0 = lshr i32 %x, 1
337   call void @use32(i32 %t0)
338   %t1 = shl i32 %y, 1
339   call void @use32(i32 %t1)
340   %t2 = and i32 %t1, %t0
341   %t3 = icmp ne i32 %t2, 0
342   ret i1 %t3
344 define i1 @t22_const_oneuse4(i32 %x, i32 %y) {
345 ; CHECK-LABEL: @t22_const_oneuse4(
346 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], 1
347 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
348 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], 1
349 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]
350 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
351 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0
352 ; CHECK-NEXT:    ret i1 [[T3]]
354   %t0 = lshr i32 %x, 1
355   call void @use32(i32 %t0)
356   %t1 = shl i32 %y, 1
357   %t2 = and i32 %t1, %t0
358   call void @use32(i32 %t2)
359   %t3 = icmp ne i32 %t2, 0
360   ret i1 %t3
362 define i1 @t23_const_oneuse5(i32 %x, i32 %y) {
363 ; CHECK-LABEL: @t23_const_oneuse5(
364 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], 1
365 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], 1
366 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
367 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]
368 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
369 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0
370 ; CHECK-NEXT:    ret i1 [[T3]]
372   %t0 = lshr i32 %x, 1
373   %t1 = shl i32 %y, 1
374   call void @use32(i32 %t1)
375   %t2 = and i32 %t1, %t0
376   call void @use32(i32 %t2)
377   %t3 = icmp ne i32 %t2, 0
378   ret i1 %t3
380 define i1 @t24_const_oneuse6(i32 %x, i32 %y) {
381 ; CHECK-LABEL: @t24_const_oneuse6(
382 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], 1
383 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
384 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], 1
385 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
386 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]
387 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
388 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0
389 ; CHECK-NEXT:    ret i1 [[T3]]
391   %t0 = lshr i32 %x, 1
392   call void @use32(i32 %t0)
393   %t1 = shl i32 %y, 1
394   call void @use32(i32 %t1)
395   %t2 = and i32 %t1, %t0
396   call void @use32(i32 %t2)
397   %t3 = icmp ne i32 %t2, 0
398   ret i1 %t3
401 define i1 @t25_var_oneuse0(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
402 ; CHECK-LABEL: @t25_var_oneuse0(
403 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]
404 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
405 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]
406 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]
407 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0
408 ; CHECK-NEXT:    ret i1 [[T3]]
410   %t0 = lshr i32 %x, %shamt0
411   call void @use32(i32 %t0)
412   %t1 = shl i32 %y, %shamt1
413   %t2 = and i32 %t1, %t0
414   %t3 = icmp ne i32 %t2, 0
415   ret i1 %t3
417 define i1 @t26_var_oneuse1(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
418 ; CHECK-LABEL: @t26_var_oneuse1(
419 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]
420 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]
421 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
422 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]
423 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0
424 ; CHECK-NEXT:    ret i1 [[T3]]
426   %t0 = lshr i32 %x, %shamt0
427   %t1 = shl i32 %y, %shamt1
428   call void @use32(i32 %t1)
429   %t2 = and i32 %t1, %t0
430   %t3 = icmp ne i32 %t2, 0
431   ret i1 %t3
433 define i1 @t27_var_oneuse2(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
434 ; CHECK-LABEL: @t27_var_oneuse2(
435 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]
436 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]
437 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]
438 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
439 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0
440 ; CHECK-NEXT:    ret i1 [[T3]]
442   %t0 = lshr i32 %x, %shamt0
443   %t1 = shl i32 %y, %shamt1
444   %t2 = and i32 %t1, %t0
445   call void @use32(i32 %t2)
446   %t3 = icmp ne i32 %t2, 0
447   ret i1 %t3
449 define i1 @t28_var_oneuse3(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
450 ; CHECK-LABEL: @t28_var_oneuse3(
451 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]
452 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
453 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]
454 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
455 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]
456 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0
457 ; CHECK-NEXT:    ret i1 [[T3]]
459   %t0 = lshr i32 %x, %shamt0
460   call void @use32(i32 %t0)
461   %t1 = shl i32 %y, %shamt1
462   call void @use32(i32 %t1)
463   %t2 = and i32 %t1, %t0
464   %t3 = icmp ne i32 %t2, 0
465   ret i1 %t3
467 define i1 @t29_var_oneuse4(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
468 ; CHECK-LABEL: @t29_var_oneuse4(
469 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]
470 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
471 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]
472 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]
473 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
474 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0
475 ; CHECK-NEXT:    ret i1 [[T3]]
477   %t0 = lshr i32 %x, %shamt0
478   call void @use32(i32 %t0)
479   %t1 = shl i32 %y, %shamt1
480   %t2 = and i32 %t1, %t0
481   call void @use32(i32 %t2)
482   %t3 = icmp ne i32 %t2, 0
483   ret i1 %t3
485 define i1 @t30_var_oneuse5(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
486 ; CHECK-LABEL: @t30_var_oneuse5(
487 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]
488 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]
489 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
490 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]
491 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
492 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0
493 ; CHECK-NEXT:    ret i1 [[T3]]
495   %t0 = lshr i32 %x, %shamt0
496   %t1 = shl i32 %y, %shamt1
497   call void @use32(i32 %t1)
498   %t2 = and i32 %t1, %t0
499   call void @use32(i32 %t2)
500   %t3 = icmp ne i32 %t2, 0
501   ret i1 %t3
503 define i1 @t31_var_oneuse6(i32 %x, i32 %y, i32 %shamt0, i32 %shamt1) {
504 ; CHECK-LABEL: @t31_var_oneuse6(
505 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], [[SHAMT0:%.*]]
506 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
507 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], [[SHAMT1:%.*]]
508 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
509 ; CHECK-NEXT:    [[T2:%.*]] = and i32 [[T1]], [[T0]]
510 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
511 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[T2]], 0
512 ; CHECK-NEXT:    ret i1 [[T3]]
514   %t0 = lshr i32 %x, %shamt0
515   call void @use32(i32 %t0)
516   %t1 = shl i32 %y, %shamt1
517   call void @use32(i32 %t1)
518   %t2 = and i32 %t1, %t0
519   call void @use32(i32 %t2)
520   %t3 = icmp ne i32 %t2, 0
521   ret i1 %t3
524 ; Shift-of-const
526 ; Ok, non-truncated shift is of constant;
527 define i1 @t32_shift_of_const_oneuse0(i32 %x, i32 %y, i32 %len) {
528 ; CHECK-LABEL: @t32_shift_of_const_oneuse0(
529 ; CHECK-NEXT:    [[T0:%.*]] = sub i32 32, [[LEN:%.*]]
530 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
531 ; CHECK-NEXT:    [[T1:%.*]] = lshr i32 -52543054, [[T0]]
532 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
533 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[LEN]], -1
534 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
535 ; CHECK-NEXT:    [[T3:%.*]] = shl i32 [[Y:%.*]], [[T2]]
536 ; CHECK-NEXT:    call void @use32(i32 [[T3]])
537 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y]], 1
538 ; CHECK-NEXT:    [[T5:%.*]] = icmp ne i32 [[TMP1]], 0
539 ; CHECK-NEXT:    ret i1 [[T5]]
541   %t0 = sub i32 32, %len
542   call void @use32(i32 %t0)
543   %t1 = lshr i32 4242424242, %t0 ; shift-of-constant
544   call void @use32(i32 %t1)
545   %t2 = add i32 %len, -1
546   call void @use32(i32 %t2)
547   %t3 = shl i32 %y, %t2
548   call void @use32(i32 %t3)
549   %t4 = and i32 %t1, %t3 ; no extra uses
550   %t5 = icmp ne i32 %t4, 0
551   ret i1 %t5
553 ; Ok, truncated shift is of constant;
554 define i1 @t33_shift_of_const_oneuse1(i32 %x, i32 %y, i32 %len) {
555 ; CHECK-LABEL: @t33_shift_of_const_oneuse1(
556 ; CHECK-NEXT:    [[T0:%.*]] = sub i32 32, [[LEN:%.*]]
557 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
558 ; CHECK-NEXT:    [[T1:%.*]] = lshr i32 [[X:%.*]], [[T0]]
559 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
560 ; CHECK-NEXT:    [[T2:%.*]] = add i32 [[LEN]], -1
561 ; CHECK-NEXT:    call void @use32(i32 [[T2]])
562 ; CHECK-NEXT:    [[T3:%.*]] = shl i32 -52543054, [[T2]]
563 ; CHECK-NEXT:    call void @use32(i32 [[T3]])
564 ; CHECK-NEXT:    ret i1 false
566   %t0 = sub i32 32, %len
567   call void @use32(i32 %t0)
568   %t1 = lshr i32 %x, %t0 ; shift-of-constant
569   call void @use32(i32 %t1)
570   %t2 = add i32 %len, -1
571   call void @use32(i32 %t2)
572   %t3 = shl i32 4242424242, %t2
573   call void @use32(i32 %t3)
574   %t4 = and i32 %t1, %t3 ; no extra uses
575   %t5 = icmp ne i32 %t4, 0
576   ret i1 %t5
579 ; Commutativity with extra uses
581 define i1 @t34_commutativity0_oneuse0(i32 %x) {
582 ; CHECK-LABEL: @t34_commutativity0_oneuse0(
583 ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
584 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], 1
585 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
586 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X]], 2
587 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]
588 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0
589 ; CHECK-NEXT:    ret i1 [[T3]]
591   %y = call i32 @gen32()
592   %t0 = lshr i32 %x, 1
593   call void @use32(i32 %t0)
594   %t1 = shl i32 %y, 1
595   %t2 = and i32 %t1, %t0
596   %t3 = icmp ne i32 %t2, 0
597   ret i1 %t3
599 define i1 @t35_commutativity0_oneuse1(i32 %x) {
600 ; CHECK-LABEL: @t35_commutativity0_oneuse1(
601 ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
602 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y]], 1
603 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
604 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
605 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]
606 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0
607 ; CHECK-NEXT:    ret i1 [[T3]]
609   %y = call i32 @gen32()
610   %t0 = lshr i32 %x, 1
611   %t1 = shl i32 %y, 1
612   call void @use32(i32 %t1)
613   %t2 = and i32 %t1, %t0
614   %t3 = icmp ne i32 %t2, 0
615   ret i1 %t3
618 define i1 @t36_commutativity1_oneuse0(i32 %y) {
619 ; CHECK-LABEL: @t36_commutativity1_oneuse0(
620 ; CHECK-NEXT:    [[X:%.*]] = call i32 @gen32()
621 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X]], 1
622 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
623 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X]], 2
624 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y:%.*]]
625 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0
626 ; CHECK-NEXT:    ret i1 [[T3]]
628   %x = call i32 @gen32()
629   %t0 = lshr i32 %x, 1
630   call void @use32(i32 %t0)
631   %t1 = shl i32 %y, 1
632   %t2 = and i32 %t0, %t1 ; "swapped"
633   %t3 = icmp ne i32 %t2, 0
634   ret i1 %t3
636 define i1 @t37_commutativity1_oneuse1(i32 %y) {
637 ; CHECK-LABEL: @t37_commutativity1_oneuse1(
638 ; CHECK-NEXT:    [[X:%.*]] = call i32 @gen32()
639 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], 1
640 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
641 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X]], 2
642 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]
643 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne i32 [[TMP2]], 0
644 ; CHECK-NEXT:    ret i1 [[T3]]
646   %x = call i32 @gen32()
647   %t0 = lshr i32 %x, 1
648   %t1 = shl i32 %y, 1
649   call void @use32(i32 %t1)
650   %t2 = and i32 %t0, %t1 ; "swapped"
651   %t3 = icmp ne i32 %t2, 0
652   ret i1 %t3
655 ; Negative tests
656 define <2 x i1> @n38_overshift(<2 x i32> %x, <2 x i32> %y) {
657 ; CHECK-LABEL: @n38_overshift(
658 ; CHECK-NEXT:    [[T0:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 15, i32 1>
659 ; CHECK-NEXT:    [[T1:%.*]] = shl <2 x i32> [[Y:%.*]], <i32 17, i32 1>
660 ; CHECK-NEXT:    [[T2:%.*]] = and <2 x i32> [[T1]], [[T0]]
661 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne <2 x i32> [[T2]], zeroinitializer
662 ; CHECK-NEXT:    ret <2 x i1> [[T3]]
664   %t0 = lshr <2 x i32> %x, <i32 15, i32 1>
665   %t1 = shl <2 x i32> %y, <i32 17, i32 1>
666   %t2 = and <2 x i32> %t1, %t0
667   %t3 = icmp ne <2 x i32> %t2, <i32 0, i32 0>
668   ret <2 x i1> %t3
671 ; As usual, don't crash given constantexpr's :/
672 @f.a = internal global i16 0, align 1
673 define i1 @constantexpr() {
674 ; CHECK-LABEL: @constantexpr(
675 ; CHECK-NEXT:  entry:
676 ; CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr @f.a, align 2
677 ; CHECK-NEXT:    [[SHR:%.*]] = lshr i16 [[TMP0]], 1
678 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i16 ptrtoint (ptr @f.a to i16), 1
679 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[CMP]] to i16
680 ; CHECK-NEXT:    [[TMP1:%.*]] = shl nuw nsw i16 1, [[ZEXT]]
681 ; CHECK-NEXT:    [[TMP2:%.*]] = and i16 [[SHR]], [[TMP1]]
682 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i16 [[TMP2]], 0
683 ; CHECK-NEXT:    ret i1 [[TOBOOL]]
685 entry:
686   %0 = load i16, ptr @f.a
687   %shr = ashr i16 %0, 1
688   %cmp = icmp ne i16 ptrtoint (ptr @f.a to i16), 1
689   %zext = zext i1 %cmp to i16
690   %shr1 = ashr i16 %shr, %zext
691   %and = and i16 %shr1, 1
692   %tobool = icmp ne i16 %and, 0
693   ret i1 %tobool
696 ; See https://bugs.llvm.org/show_bug.cgi?id=44802
697 define i1 @pr44802(i3 %a, i3 %x, i3 %y) {
698 ; CHECK-LABEL: @pr44802(
699 ; CHECK-NEXT:    [[T0:%.*]] = icmp ne i3 [[A:%.*]], 0
700 ; CHECK-NEXT:    [[T1:%.*]] = zext i1 [[T0]] to i3
701 ; CHECK-NEXT:    [[T2:%.*]] = lshr i3 [[X:%.*]], [[T1]]
702 ; CHECK-NEXT:    [[T3:%.*]] = shl i3 [[Y:%.*]], [[T1]]
703 ; CHECK-NEXT:    [[T4:%.*]] = and i3 [[T2]], [[T3]]
704 ; CHECK-NEXT:    [[T5:%.*]] = icmp ne i3 [[T4]], 0
705 ; CHECK-NEXT:    ret i1 [[T5]]
707   %t0 = icmp ne i3 %a, 0
708   %t1 = zext i1 %t0 to i3
709   %t2 = lshr i3 %x, %t1
710   %t3 = shl i3 %y, %t1
711   %t4 = and i3 %t2, %t3
712   %t5 = icmp ne i3 %t4, 0
713   ret i1 %t5