[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / InstCombine / shift-amount-reassociation-in-bittest.ll
blobc0bce48b3bedcac999172f6401f8302dcedf6a27
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt %s -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:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
17 ; CHECK-NEXT:    ret i1 [[TMP3]]
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:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
30 ; CHECK-NEXT:    ret i1 [[TMP3]]
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:    [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
45 ; CHECK-NEXT:    ret i1 [[TMP3]]
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:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
61 ; CHECK-NEXT:    ret i1 [[TMP3]]
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:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
76 ; CHECK-NEXT:    ret i1 [[TMP3]]
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:%.*]], <i32 2, i32 2>
123 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i32> [[TMP1]], [[Y:%.*]]
124 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
125 ; CHECK-NEXT:    ret <2 x i1> [[TMP3]]
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:    [[TMP3:%.*]] = icmp ne <2 x i32> [[TMP2]], zeroinitializer
138 ; CHECK-NEXT:    ret <2 x i1> [[TMP3]]
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_undef0(<3 x i32> %x, <3 x i32> %y) {
147 ; CHECK-LABEL: @t9_const_lshr_shl_ne_vec_undef0(
148 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 undef, i32 2>
149 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
150 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
151 ; CHECK-NEXT:    ret <3 x i1> [[TMP3]]
153   %t0 = lshr <3 x i32> %x, <i32 1, i32 undef, 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_undef1(<3 x i32> %x, <3 x i32> %y) {
160 ; CHECK-LABEL: @t10_const_lshr_shl_ne_vec_undef1(
161 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 undef, i32 2>
162 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
163 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
164 ; CHECK-NEXT:    ret <3 x i1> [[TMP3]]
166   %t0 = lshr <3 x i32> %x, <i32 1, i32 1, i32 1>
167   %t1 = shl <3 x i32> %y, <i32 1, i32 undef, 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_undef2(<3 x i32> %x, <3 x i32> %y) {
173 ; CHECK-LABEL: @t11_const_lshr_shl_ne_vec_undef2(
174 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 2, i32 2>
175 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
176 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
177 ; CHECK-NEXT:    ret <3 x i1> [[TMP3]]
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 undef, i32 0>
183   ret <3 x i1> %t3
185 define <3 x i1> @t12_const_lshr_shl_ne_vec_undef3(<3 x i32> %x, <3 x i32> %y) {
186 ; CHECK-LABEL: @t12_const_lshr_shl_ne_vec_undef3(
187 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 undef, i32 2>
188 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
189 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
190 ; CHECK-NEXT:    ret <3 x i1> [[TMP3]]
192   %t0 = lshr <3 x i32> %x, <i32 1, i32 undef, i32 1>
193   %t1 = shl <3 x i32> %y, <i32 1, i32 undef, 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_undef4(<3 x i32> %x, <3 x i32> %y) {
199 ; CHECK-LABEL: @t13_const_lshr_shl_ne_vec_undef4(
200 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 undef, i32 2>
201 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
202 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
203 ; CHECK-NEXT:    ret <3 x i1> [[TMP3]]
205   %t0 = lshr <3 x i32> %x, <i32 1, i32 1, i32 1>
206   %t1 = shl <3 x i32> %y, <i32 1, i32 undef, i32 1>
207   %t2 = and <3 x i32> %t1, %t0
208   %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 undef, i32 0>
209   ret <3 x i1> %t3
211 define <3 x i1> @t14_const_lshr_shl_ne_vec_undef5(<3 x i32> %x, <3 x i32> %y) {
212 ; CHECK-LABEL: @t14_const_lshr_shl_ne_vec_undef5(
213 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 undef, i32 2>
214 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
215 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
216 ; CHECK-NEXT:    ret <3 x i1> [[TMP3]]
218   %t0 = lshr <3 x i32> %x, <i32 1, i32 undef, 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 undef, i32 0>
222   ret <3 x i1> %t3
224 define <3 x i1> @t15_const_lshr_shl_ne_vec_undef6(<3 x i32> %x, <3 x i32> %y) {
225 ; CHECK-LABEL: @t15_const_lshr_shl_ne_vec_undef6(
226 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr <3 x i32> [[X:%.*]], <i32 2, i32 undef, i32 2>
227 ; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i32> [[TMP1]], [[Y:%.*]]
228 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne <3 x i32> [[TMP2]], zeroinitializer
229 ; CHECK-NEXT:    ret <3 x i1> [[TMP3]]
231   %t0 = lshr <3 x i32> %x, <i32 1, i32 undef, i32 1>
232   %t1 = shl <3 x i32> %y, <i32 1, i32 undef, i32 1>
233   %t2 = and <3 x i32> %t1, %t0
234   %t3 = icmp ne <3 x i32> %t2, <i32 0, i32 undef, 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:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
248 ; CHECK-NEXT:    ret i1 [[TMP3]]
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:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
264 ; CHECK-NEXT:    ret i1 [[TMP3]]
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:%.*]] = shl i32 [[Y:%.*]], 2
283 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[X]]
284 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
285 ; CHECK-NEXT:    ret i1 [[TMP3]]
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:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
301 ; CHECK-NEXT:    ret i1 [[TMP3]]
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 ; Commutativity with extra uses
526 define i1 @t32_commutativity0_oneuse0(i32 %x) {
527 ; CHECK-LABEL: @t32_commutativity0_oneuse0(
528 ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
529 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X:%.*]], 1
530 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
531 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[Y]], 2
532 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[X]]
533 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
534 ; CHECK-NEXT:    ret i1 [[TMP3]]
536   %y = call i32 @gen32()
537   %t0 = lshr i32 %x, 1
538   call void @use32(i32 %t0)
539   %t1 = shl i32 %y, 1
540   %t2 = and i32 %t1, %t0
541   %t3 = icmp ne i32 %t2, 0
542   ret i1 %t3
544 define i1 @t33_commutativity0_oneuse1(i32 %x) {
545 ; CHECK-LABEL: @t33_commutativity0_oneuse1(
546 ; CHECK-NEXT:    [[Y:%.*]] = call i32 @gen32()
547 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y]], 1
548 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
549 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X:%.*]], 2
550 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]
551 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
552 ; CHECK-NEXT:    ret i1 [[TMP3]]
554   %y = call i32 @gen32()
555   %t0 = lshr i32 %x, 1
556   %t1 = shl i32 %y, 1
557   call void @use32(i32 %t1)
558   %t2 = and i32 %t1, %t0
559   %t3 = icmp ne i32 %t2, 0
560   ret i1 %t3
563 define i1 @t34_commutativity1_oneuse0(i32 %y) {
564 ; CHECK-LABEL: @t34_commutativity1_oneuse0(
565 ; CHECK-NEXT:    [[X:%.*]] = call i32 @gen32()
566 ; CHECK-NEXT:    [[T0:%.*]] = lshr i32 [[X]], 1
567 ; CHECK-NEXT:    call void @use32(i32 [[T0]])
568 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[Y:%.*]], 2
569 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[X]]
570 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
571 ; CHECK-NEXT:    ret i1 [[TMP3]]
573   %x = call i32 @gen32()
574   %t0 = lshr i32 %x, 1
575   call void @use32(i32 %t0)
576   %t1 = shl i32 %y, 1
577   %t2 = and i32 %t0, %t1 ; "swapped"
578   %t3 = icmp ne i32 %t2, 0
579   ret i1 %t3
581 define i1 @t35_commutativity1_oneuse1(i32 %y) {
582 ; CHECK-LABEL: @t35_commutativity1_oneuse1(
583 ; CHECK-NEXT:    [[X:%.*]] = call i32 @gen32()
584 ; CHECK-NEXT:    [[T1:%.*]] = shl i32 [[Y:%.*]], 1
585 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
586 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X]], 2
587 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], [[Y]]
588 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
589 ; CHECK-NEXT:    ret i1 [[TMP3]]
591   %x = call i32 @gen32()
592   %t0 = lshr i32 %x, 1
593   %t1 = shl i32 %y, 1
594   call void @use32(i32 %t1)
595   %t2 = and i32 %t0, %t1 ; "swapped"
596   %t3 = icmp ne i32 %t2, 0
597   ret i1 %t3
600 ; Negative tests
601 define <2 x i1> @n36_overshift(<2 x i32> %x, <2 x i32> %y) {
602 ; CHECK-LABEL: @n36_overshift(
603 ; CHECK-NEXT:    [[T0:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 15, i32 1>
604 ; CHECK-NEXT:    [[T1:%.*]] = shl <2 x i32> [[Y:%.*]], <i32 17, i32 1>
605 ; CHECK-NEXT:    [[T2:%.*]] = and <2 x i32> [[T1]], [[T0]]
606 ; CHECK-NEXT:    [[T3:%.*]] = icmp ne <2 x i32> [[T2]], zeroinitializer
607 ; CHECK-NEXT:    ret <2 x i1> [[T3]]
609   %t0 = lshr <2 x i32> %x, <i32 15, i32 1>
610   %t1 = shl <2 x i32> %y, <i32 17, i32 1>
611   %t2 = and <2 x i32> %t1, %t0
612   %t3 = icmp ne <2 x i32> %t2, <i32 0, i32 0>
613   ret <2 x i1> %t3