1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
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.
9
10; Basic scalar test with constants
11
12define 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]]
18;
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
24}
25define 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]]
31;
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
37}
38
39; We are ok with 'eq' predicate too.
40define 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]]
46;
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
52}
53
54; Basic scalar test with constants after folding
55
56define 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]]
62;
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
70}
71define 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]]
77;
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
85}
86
87; Completely variable shift amounts
88
89define 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]]
96;
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
102}
103define 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]]
110;
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
116}
117
118; Very basic vector tests
119
120define <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]]
126;
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
132}
133define <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]]
139;
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
145}
146define <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]]
152;
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
158}
159define <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]]
165;
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
171}
172define <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]]
178;
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
184}
185define <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]]
191;
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
197}
198define <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]]
204;
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
210}
211define <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]]
217;
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
223}
224define <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]]
230;
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
236}
237
238; Commutativity tests
239
240declare i32 @gen32()
241
242define 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]]
249;
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
256}
257
258define 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]]
265;
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
272}
273
274; One-use tests
275
276declare void @use32(i32)
277
278define 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:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
285; CHECK-NEXT:    ret i1 [[TMP3]]
286;
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
293}
294define 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]]
302;
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
309}
310define 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]]
318;
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
325}
326define 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]]
335;
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
343}
344define 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]]
353;
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
361}
362define 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]]
371;
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
379}
380define 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]]
390;
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
399}
400
401define 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]]
409;
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
416}
417define 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]]
425;
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
432}
433define 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]]
441;
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
448}
449define 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]]
458;
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
466}
467define 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]]
476;
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
484}
485define 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]]
494;
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
502}
503define 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]]
513;
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
522}
523
524; Shift-of-const
525
526; Ok, non-truncated shift is of constant;
527define 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:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
539; CHECK-NEXT:    ret i1 [[TMP2]]
540;
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
552}
553; Ok, truncated shift is of constant;
554define 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
565;
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
577}
578
579; Commutativity with extra uses
580
581define 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:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
589; CHECK-NEXT:    ret i1 [[TMP3]]
590;
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
598}
599define 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:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
607; CHECK-NEXT:    ret i1 [[TMP3]]
608;
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
616}
617
618define 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:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
626; CHECK-NEXT:    ret i1 [[TMP3]]
627;
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
635}
636define 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:    [[TMP3:%.*]] = icmp ne i32 [[TMP2]], 0
644; CHECK-NEXT:    ret i1 [[TMP3]]
645;
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
653}
654
655; Negative tests
656define <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]]
663;
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
669}
670
671; As usual, don't crash given constantexpr's :/
672@f.a = internal global i16 0
673define i1 @constantexpr() {
674; CHECK-LABEL: @constantexpr(
675; CHECK-NEXT:  entry:
676; CHECK-NEXT:    [[TMP0:%.*]] = load i16, i16* @f.a, align 2
677; CHECK-NEXT:    [[TMP1:%.*]] = lshr i16 [[TMP0]], 1
678; CHECK-NEXT:    [[TMP2:%.*]] = and i16 [[TMP1]], shl (i16 1, i16 zext (i1 icmp ne (i16 ptrtoint (i16* @f.a to i16), i16 1) to i16))
679; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i16 [[TMP2]], 0
680; CHECK-NEXT:    ret i1 [[TOBOOL]]
681;
682entry:
683  %0 = load i16, i16* @f.a
684  %shr = ashr i16 %0, 1
685  %shr1 = ashr i16 %shr, zext (i1 icmp ne (i16 ptrtoint (i16* @f.a to i16), i16 1) to i16)
686  %and = and i16 %shr1, 1
687  %tobool = icmp ne i16 %and, 0
688  ret i1 %tobool
689}
690
691; See https://bugs.llvm.org/show_bug.cgi?id=44802
692define i1 @pr44802(i3 %a, i3 %x, i3 %y) {
693; CHECK-LABEL: @pr44802(
694; CHECK-NEXT:    [[T0:%.*]] = icmp ne i3 [[A:%.*]], 0
695; CHECK-NEXT:    [[T1:%.*]] = zext i1 [[T0]] to i3
696; CHECK-NEXT:    [[T2:%.*]] = lshr i3 [[X:%.*]], [[T1]]
697; CHECK-NEXT:    [[T3:%.*]] = shl i3 [[Y:%.*]], [[T1]]
698; CHECK-NEXT:    [[T4:%.*]] = and i3 [[T2]], [[T3]]
699; CHECK-NEXT:    [[T5:%.*]] = icmp ne i3 [[T4]], 0
700; CHECK-NEXT:    ret i1 [[T5]]
701;
702  %t0 = icmp ne i3 %a, 0
703  %t1 = zext i1 %t0 to i3
704  %t2 = lshr i3 %x, %t1
705  %t3 = shl i3 %y, %t1
706  %t4 = and i3 %t2, %t3
707  %t5 = icmp ne i3 %t4, 0
708  ret i1 %t5
709}
710