xref: /llvm-project/llvm/test/Transforms/InstCombine/ashr-lshr.ll (revision 38fffa630ee80163dc65e759392ad29798905679)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4define i32 @ashr_lshr_exact_ashr_only(i32 %x, i32 %y) {
5; CHECK-LABEL: @ashr_lshr_exact_ashr_only(
6; CHECK-NEXT:    [[CMP12:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]
7; CHECK-NEXT:    ret i32 [[CMP12]]
8;
9  %cmp = icmp sgt i32 %x, -1
10  %l = lshr i32 %x, %y
11  %r = ashr exact i32 %x, %y
12  %ret = select i1 %cmp, i32 %l, i32 %r
13  ret i32 %ret
14}
15
16define i32 @ashr_lshr_no_exact(i32 %x, i32 %y) {
17; CHECK-LABEL: @ashr_lshr_no_exact(
18; CHECK-NEXT:    [[CMP12:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]
19; CHECK-NEXT:    ret i32 [[CMP12]]
20;
21  %cmp = icmp sgt i32 %x, -1
22  %l = lshr i32 %x, %y
23  %r = ashr i32 %x, %y
24  %ret = select i1 %cmp, i32 %l, i32 %r
25  ret i32 %ret
26}
27
28define i32 @ashr_lshr_exact_both(i32 %x, i32 %y) {
29; CHECK-LABEL: @ashr_lshr_exact_both(
30; CHECK-NEXT:    [[CMP12:%.*]] = ashr exact i32 [[X:%.*]], [[Y:%.*]]
31; CHECK-NEXT:    ret i32 [[CMP12]]
32;
33  %cmp = icmp sgt i32 %x, -1
34  %l = lshr exact i32 %x, %y
35  %r = ashr exact i32 %x, %y
36  %ret = select i1 %cmp, i32 %l, i32 %r
37  ret i32 %ret
38}
39
40define i32 @ashr_lshr_exact_lshr_only(i32 %x, i32 %y) {
41; CHECK-LABEL: @ashr_lshr_exact_lshr_only(
42; CHECK-NEXT:    [[CMP12:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]
43; CHECK-NEXT:    ret i32 [[CMP12]]
44;
45  %cmp = icmp sgt i32 %x, -1
46  %l = lshr exact i32 %x, %y
47  %r = ashr i32 %x, %y
48  %ret = select i1 %cmp, i32 %l, i32 %r
49  ret i32 %ret
50}
51
52define i32 @ashr_lshr2(i32 %x, i32 %y) {
53; CHECK-LABEL: @ashr_lshr2(
54; CHECK-NEXT:    [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]
55; CHECK-NEXT:    ret i32 [[CMP1]]
56;
57  %cmp = icmp sgt i32 %x, 5
58  %l = lshr i32 %x, %y
59  %r = ashr exact i32 %x, %y
60  %ret = select i1 %cmp, i32 %l, i32 %r
61  ret i32 %ret
62}
63
64define i128 @ashr_lshr2_i128(i128 %x, i128 %y) {
65; CHECK-LABEL: @ashr_lshr2_i128(
66; CHECK-NEXT:    [[CMP1:%.*]] = ashr i128 [[X:%.*]], [[Y:%.*]]
67; CHECK-NEXT:    ret i128 [[CMP1]]
68;
69  %cmp = icmp sgt i128 %x, 5
70  %l = lshr i128 %x, %y
71  %r = ashr exact i128 %x, %y
72  %ret = select i1 %cmp, i128 %l, i128 %r
73  ret i128 %ret
74}
75
76define <2 x i32> @ashr_lshr_splat_vec(<2 x i32> %x, <2 x i32> %y) {
77; CHECK-LABEL: @ashr_lshr_splat_vec(
78; CHECK-NEXT:    [[CMP12:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
79; CHECK-NEXT:    ret <2 x i32> [[CMP12]]
80;
81  %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
82  %l = lshr <2 x i32> %x, %y
83  %r = ashr <2 x i32> %x, %y
84  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r
85  ret <2 x i32> %ret
86}
87
88define <2 x i32> @ashr_lshr_splat_vec2(<2 x i32> %x, <2 x i32> %y) {
89; CHECK-LABEL: @ashr_lshr_splat_vec2(
90; CHECK-NEXT:    [[CMP12:%.*]] = ashr exact <2 x i32> [[X:%.*]], [[Y:%.*]]
91; CHECK-NEXT:    ret <2 x i32> [[CMP12]]
92;
93  %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
94  %l = lshr exact <2 x i32> %x, %y
95  %r = ashr exact <2 x i32> %x, %y
96  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r
97  ret <2 x i32> %ret
98}
99
100define <2 x i32> @ashr_lshr_splat_vec3(<2 x i32> %x, <2 x i32> %y) {
101; CHECK-LABEL: @ashr_lshr_splat_vec3(
102; CHECK-NEXT:    [[CMP12:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
103; CHECK-NEXT:    ret <2 x i32> [[CMP12]]
104;
105  %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
106  %l = lshr exact <2 x i32> %x, %y
107  %r = ashr <2 x i32> %x, %y
108  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r
109  ret <2 x i32> %ret
110}
111
112define <2 x i32> @ashr_lshr_splat_vec4(<2 x i32> %x, <2 x i32> %y) {
113; CHECK-LABEL: @ashr_lshr_splat_vec4(
114; CHECK-NEXT:    [[CMP12:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
115; CHECK-NEXT:    ret <2 x i32> [[CMP12]]
116;
117  %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
118  %l = lshr <2 x i32> %x, %y
119  %r = ashr exact <2 x i32> %x, %y
120  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r
121  ret <2 x i32> %ret
122}
123
124define <2 x i32> @ashr_lshr_nonsplat_vec(<2 x i32> %x, <2 x i32> %y) {
125; CHECK-LABEL: @ashr_lshr_nonsplat_vec(
126; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
127; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
128;
129  %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 1>
130  %l = lshr <2 x i32> %x, %y
131  %r = ashr <2 x i32> %x, %y
132  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r
133  ret <2 x i32> %ret
134}
135
136define <2 x i32> @ashr_lshr_nonsplat_vec2(<2 x i32> %x, <2 x i32> %y) {
137; CHECK-LABEL: @ashr_lshr_nonsplat_vec2(
138; CHECK-NEXT:    [[CMP1:%.*]] = ashr exact <2 x i32> [[X:%.*]], [[Y:%.*]]
139; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
140;
141  %cmp = icmp sgt <2 x i32> %x, <i32 2, i32 4>
142  %l = lshr exact <2 x i32> %x, %y
143  %r = ashr exact <2 x i32> %x, %y
144  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r
145  ret <2 x i32> %ret
146}
147
148define <2 x i32> @ashr_lshr_nonsplat_vec3(<2 x i32> %x, <2 x i32> %y) {
149; CHECK-LABEL: @ashr_lshr_nonsplat_vec3(
150; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
151; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
152;
153  %cmp = icmp sgt <2 x i32> %x, <i32 5, i32 6>
154  %l = lshr exact <2 x i32> %x, %y
155  %r = ashr <2 x i32> %x, %y
156  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r
157  ret <2 x i32> %ret
158}
159
160define <2 x i32> @ashr_lshr_nonsplat_vec4(<2 x i32> %x, <2 x i32> %y) {
161; CHECK-LABEL: @ashr_lshr_nonsplat_vec4(
162; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
163; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
164;
165  %cmp = icmp sgt <2 x i32> %x, <i32 8, i32 7>
166  %l = lshr <2 x i32> %x, %y
167  %r = ashr exact <2 x i32> %x, %y
168  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r
169  ret <2 x i32> %ret
170}
171
172define i32 @ashr_lshr_cst(i32 %x, i32 %y) {
173; CHECK-LABEL: @ashr_lshr_cst(
174; CHECK-NEXT:    [[CMP1:%.*]] = ashr i32 [[X:%.*]], 8
175; CHECK-NEXT:    ret i32 [[CMP1]]
176;
177  %cmp = icmp slt i32 %x, 1
178  %l = lshr i32 %x, 8
179  %r = ashr exact i32 %x, 8
180  %ret = select i1 %cmp, i32 %r, i32 %l
181  ret i32 %ret
182}
183
184define i32 @ashr_lshr_cst2(i32 %x, i32 %y) {
185; CHECK-LABEL: @ashr_lshr_cst2(
186; CHECK-NEXT:    [[CMP12:%.*]] = ashr i32 [[X:%.*]], 8
187; CHECK-NEXT:    ret i32 [[CMP12]]
188;
189  %cmp = icmp sgt i32 %x, -1
190  %l = lshr i32 %x, 8
191  %r = ashr exact i32 %x, 8
192  %ret = select i1 %cmp, i32 %l, i32 %r
193  ret i32 %ret
194}
195
196define i32 @ashr_lshr_inv(i32 %x, i32 %y) {
197; CHECK-LABEL: @ashr_lshr_inv(
198; CHECK-NEXT:    [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]
199; CHECK-NEXT:    ret i32 [[CMP1]]
200;
201  %cmp = icmp slt i32 %x, 1
202  %l = lshr i32 %x, %y
203  %r = ashr exact i32 %x, %y
204  %ret = select i1 %cmp, i32 %r, i32 %l
205  ret i32 %ret
206}
207
208define i32 @ashr_lshr_inv2(i32 %x, i32 %y) {
209; CHECK-LABEL: @ashr_lshr_inv2(
210; CHECK-NEXT:    [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]
211; CHECK-NEXT:    ret i32 [[CMP1]]
212;
213  %cmp = icmp slt i32 %x, 7
214  %l = lshr i32 %x, %y
215  %r = ashr exact i32 %x, %y
216  %ret = select i1 %cmp, i32 %r, i32 %l
217  ret i32 %ret
218}
219
220define <2 x i32> @ashr_lshr_inv_splat_vec(<2 x i32> %x, <2 x i32> %y) {
221; CHECK-LABEL: @ashr_lshr_inv_splat_vec(
222; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
223; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
224;
225  %cmp = icmp slt <2 x i32> %x, <i32 1, i32 1>
226  %l = lshr <2 x i32> %x, %y
227  %r = ashr exact <2 x i32> %x, %y
228  %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l
229  ret <2 x i32> %ret
230}
231
232define <2 x i32> @ashr_lshr_inv_nonsplat_vec(<2 x i32> %x, <2 x i32> %y) {
233; CHECK-LABEL: @ashr_lshr_inv_nonsplat_vec(
234; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
235; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
236;
237  %cmp = icmp slt <2 x i32> %x, <i32 4, i32 5>
238  %l = lshr <2 x i32> %x, %y
239  %r = ashr exact <2 x i32> %x, %y
240  %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l
241  ret <2 x i32> %ret
242}
243
244define <2 x i32> @ashr_lshr_vec_poison(<2 x i32> %x, <2 x i32> %y) {
245; CHECK-LABEL: @ashr_lshr_vec_poison(
246; CHECK-NEXT:    [[CMP12:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
247; CHECK-NEXT:    ret <2 x i32> [[CMP12]]
248;
249  %cmp = icmp sgt <2 x i32> %x, <i32 poison, i32 -1>
250  %l = lshr <2 x i32> %x, %y
251  %r = ashr exact <2 x i32> %x, %y
252  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r
253  ret <2 x i32> %ret
254}
255
256define <2 x i32> @ashr_lshr_vec_poison2(<2 x i32> %x, <2 x i32> %y) {
257; CHECK-LABEL: @ashr_lshr_vec_poison2(
258; CHECK-NEXT:    [[CMP1:%.*]] = ashr exact <2 x i32> [[X:%.*]], [[Y:%.*]]
259; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
260;
261  %cmp = icmp slt <2 x i32> %x, <i32 1, i32 poison>
262  %l = lshr exact <2 x i32> %x, %y
263  %r = ashr exact <2 x i32> %x, %y
264  %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l
265  ret <2 x i32> %ret
266}
267
268; Negative tests
269
270define i32 @ashr_lshr_wrong_cst(i32 %x, i32 %y) {
271; CHECK-LABEL: @ashr_lshr_wrong_cst(
272; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -2
273; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]
274; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 [[X]], [[Y]]
275; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]]
276; CHECK-NEXT:    ret i32 [[RET]]
277;
278  %cmp = icmp sgt i32 %x, -2
279  %l = lshr i32 %x, %y
280  %r = ashr exact i32 %x, %y
281  %ret = select i1 %cmp, i32 %l, i32 %r
282  ret i32 %ret
283}
284
285define i32 @ashr_lshr_wrong_cst2(i32 %x, i32 %y) {
286; CHECK-LABEL: @ashr_lshr_wrong_cst2(
287; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], -1
288; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]
289; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 [[X]], [[Y]]
290; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[R]], i32 [[L]]
291; CHECK-NEXT:    ret i32 [[RET]]
292;
293  %cmp = icmp slt i32 %x, -1
294  %l = lshr i32 %x, %y
295  %r = ashr exact i32 %x, %y
296  %ret = select i1 %cmp, i32 %r, i32 %l
297  ret i32 %ret
298}
299
300define i32 @ashr_lshr_wrong_cond(i32 %x, i32 %y) {
301; CHECK-LABEL: @ashr_lshr_wrong_cond(
302; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -2
303; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]
304; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Y]]
305; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]]
306; CHECK-NEXT:    ret i32 [[RET]]
307;
308  %cmp = icmp sge i32 %x, -1
309  %l = lshr i32 %x, %y
310  %r = ashr i32 %x, %y
311  %ret = select i1 %cmp, i32 %l, i32 %r
312  ret i32 %ret
313}
314
315define i32 @ashr_lshr_shift_wrong_pred(i32 %x, i32 %y, i32 %z) {
316; CHECK-LABEL: @ashr_lshr_shift_wrong_pred(
317; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
318; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]
319; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Y]]
320; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]]
321; CHECK-NEXT:    ret i32 [[RET]]
322;
323  %cmp = icmp sle i32 %x, 0
324  %l = lshr i32 %x, %y
325  %r = ashr i32 %x, %y
326  %ret = select i1 %cmp, i32 %l, i32 %r
327  ret i32 %ret
328}
329
330define i32 @ashr_lshr_shift_wrong_pred2(i32 %x, i32 %y, i32 %z) {
331; CHECK-LABEL: @ashr_lshr_shift_wrong_pred2(
332; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]
333; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Y]]
334; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[Z:%.*]], 0
335; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP1]], i32 [[R]], i32 [[L]]
336; CHECK-NEXT:    ret i32 [[RET]]
337;
338  %cmp = icmp sge i32 %z, 0
339  %l = lshr i32 %x, %y
340  %r = ashr i32 %x, %y
341  %ret = select i1 %cmp, i32 %l, i32 %r
342  ret i32 %ret
343}
344
345define i32 @ashr_lshr_wrong_operands(i32 %x, i32 %y) {
346; CHECK-LABEL: @ashr_lshr_wrong_operands(
347; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]
348; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Y]]
349; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X]], 0
350; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP1]], i32 [[L]], i32 [[R]]
351; CHECK-NEXT:    ret i32 [[RET]]
352;
353  %cmp = icmp sge i32 %x, 0
354  %l = lshr i32 %x, %y
355  %r = ashr i32 %x, %y
356  %ret = select i1 %cmp, i32 %r, i32 %l
357  ret i32 %ret
358}
359
360define i32 @ashr_lshr_no_ashr(i32 %x, i32 %y) {
361; CHECK-LABEL: @ashr_lshr_no_ashr(
362; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]
363; CHECK-NEXT:    [[R:%.*]] = xor i32 [[X]], [[Y]]
364; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X]], 0
365; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP1]], i32 [[R]], i32 [[L]]
366; CHECK-NEXT:    ret i32 [[RET]]
367;
368  %cmp = icmp sge i32 %x, 0
369  %l = lshr i32 %x, %y
370  %r = xor i32 %x, %y
371  %ret = select i1 %cmp, i32 %l, i32 %r
372  ret i32 %ret
373}
374
375define i32 @ashr_lshr_shift_amt_mismatch(i32 %x, i32 %y, i32 %z) {
376; CHECK-LABEL: @ashr_lshr_shift_amt_mismatch(
377; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]
378; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Z:%.*]]
379; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X]], 0
380; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP1]], i32 [[R]], i32 [[L]]
381; CHECK-NEXT:    ret i32 [[RET]]
382;
383  %cmp = icmp sge i32 %x, 0
384  %l = lshr i32 %x, %y
385  %r = ashr i32 %x, %z
386  %ret = select i1 %cmp, i32 %l, i32 %r
387  ret i32 %ret
388}
389
390define i32 @ashr_lshr_shift_base_mismatch(i32 %x, i32 %y, i32 %z) {
391; CHECK-LABEL: @ashr_lshr_shift_base_mismatch(
392; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]
393; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[Z:%.*]], [[Y]]
394; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X]], 0
395; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP1]], i32 [[R]], i32 [[L]]
396; CHECK-NEXT:    ret i32 [[RET]]
397;
398  %cmp = icmp sge i32 %x, 0
399  %l = lshr i32 %x, %y
400  %r = ashr i32 %z, %y
401  %ret = select i1 %cmp, i32 %l, i32 %r
402  ret i32 %ret
403}
404
405define i32 @ashr_lshr_no_lshr(i32 %x, i32 %y) {
406; CHECK-LABEL: @ashr_lshr_no_lshr(
407; CHECK-NEXT:    [[L:%.*]] = add i32 [[X:%.*]], [[Y:%.*]]
408; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Y]]
409; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[X]], 0
410; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP1]], i32 [[R]], i32 [[L]]
411; CHECK-NEXT:    ret i32 [[RET]]
412;
413  %cmp = icmp sge i32 %x, 0
414  %l = add i32 %x, %y
415  %r = ashr i32 %x, %y
416  %ret = select i1 %cmp, i32 %l, i32 %r
417  ret i32 %ret
418}
419
420define <2 x i32> @ashr_lshr_vec_wrong_pred(<2 x i32> %x, <2 x i32> %y) {
421; CHECK-LABEL: @ashr_lshr_vec_wrong_pred(
422; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], splat (i32 1)
423; CHECK-NEXT:    [[L:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]]
424; CHECK-NEXT:    [[R:%.*]] = ashr <2 x i32> [[X]], [[Y]]
425; CHECK-NEXT:    [[RET:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[L]], <2 x i32> [[R]]
426; CHECK-NEXT:    ret <2 x i32> [[RET]]
427;
428  %cmp = icmp sle <2 x i32> %x, zeroinitializer
429  %l = lshr <2 x i32> %x, %y
430  %r = ashr <2 x i32> %x, %y
431  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r
432  ret <2 x i32> %ret
433}
434
435define <2 x i32> @ashr_lshr_inv_vec_wrong_pred(<2 x i32> %x, <2 x i32> %y) {
436; CHECK-LABEL: @ashr_lshr_inv_vec_wrong_pred(
437; CHECK-NEXT:    [[L:%.*]] = lshr <2 x i32> [[X:%.*]], [[Y:%.*]]
438; CHECK-NEXT:    [[R:%.*]] = ashr <2 x i32> [[X]], [[Y]]
439; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt <2 x i32> [[X]], zeroinitializer
440; CHECK-NEXT:    [[RET:%.*]] = select <2 x i1> [[CMP1]], <2 x i32> [[L]], <2 x i32> [[R]]
441; CHECK-NEXT:    ret <2 x i32> [[RET]]
442;
443  %cmp = icmp sge <2 x i32> %x, zeroinitializer
444  %l = lshr <2 x i32> %x, %y
445  %r = ashr <2 x i32> %x, %y
446  %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l
447  ret <2 x i32> %ret
448}
449
450define i32 @lshr_sub_nsw(i32 %x, i32 %y) {
451; CHECK-LABEL: @lshr_sub_nsw(
452; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
453; CHECK-NEXT:    [[SHR:%.*]] = zext i1 [[TMP1]] to i32
454; CHECK-NEXT:    ret i32 [[SHR]]
455;
456  %sub = sub nsw i32 %x, %y
457  %shr = lshr i32 %sub, 31
458  ret i32 %shr
459}
460
461; negative test - must shift sign-bit
462
463define i32 @lshr_sub_wrong_amount(i32 %x, i32 %y) {
464; CHECK-LABEL: @lshr_sub_wrong_amount(
465; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
466; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[SUB]], 30
467; CHECK-NEXT:    ret i32 [[SHR]]
468;
469  %sub = sub nsw i32 %x, %y
470  %shr = lshr i32 %sub, 30
471  ret i32 %shr
472}
473
474; negative test - must have nsw
475
476define i32 @lshr_sub(i32 %x, i32 %y) {
477; CHECK-LABEL: @lshr_sub(
478; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
479; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[SUB]], 31
480; CHECK-NEXT:    ret i32 [[SHR]]
481;
482  %sub = sub i32 %x, %y
483  %shr = lshr i32 %sub, 31
484  ret i32 %shr
485}
486
487; negative test - one-use
488
489define i32 @lshr_sub_nsw_extra_use(i32 %x, i32 %y, ptr %p) {
490; CHECK-LABEL: @lshr_sub_nsw_extra_use(
491; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
492; CHECK-NEXT:    store i32 [[SUB]], ptr [[P:%.*]], align 4
493; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[SUB]], 31
494; CHECK-NEXT:    ret i32 [[SHR]]
495;
496  %sub = sub nsw i32 %x, %y
497  store i32 %sub, ptr %p
498  %shr = lshr i32 %sub, 31
499  ret i32 %shr
500}
501
502define <3 x i42> @lshr_sub_nsw_splat(<3 x i42> %x, <3 x i42> %y) {
503; CHECK-LABEL: @lshr_sub_nsw_splat(
504; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <3 x i42> [[X:%.*]], [[Y:%.*]]
505; CHECK-NEXT:    [[SHR:%.*]] = zext <3 x i1> [[TMP1]] to <3 x i42>
506; CHECK-NEXT:    ret <3 x i42> [[SHR]]
507;
508  %sub = sub nsw <3 x i42> %x, %y
509  %shr = lshr <3 x i42> %sub, <i42 41, i42 41, i42 41>
510  ret <3 x i42> %shr
511}
512
513define <3 x i42> @lshr_sub_nsw_splat_poison(<3 x i42> %x, <3 x i42> %y) {
514; CHECK-LABEL: @lshr_sub_nsw_splat_poison(
515; CHECK-NEXT:    [[SUB:%.*]] = sub nsw <3 x i42> [[X:%.*]], [[Y:%.*]]
516; CHECK-NEXT:    [[SHR:%.*]] = lshr <3 x i42> [[SUB]], <i42 41, i42 poison, i42 41>
517; CHECK-NEXT:    ret <3 x i42> [[SHR]]
518;
519  %sub = sub nsw <3 x i42> %x, %y
520  %shr = lshr <3 x i42> %sub, <i42 41, i42 poison, i42 41>
521  ret <3 x i42> %shr
522}
523
524define i17 @ashr_sub_nsw(i17 %x, i17 %y) {
525; CHECK-LABEL: @ashr_sub_nsw(
526; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i17 [[X:%.*]], [[Y:%.*]]
527; CHECK-NEXT:    [[SHR:%.*]] = sext i1 [[TMP1]] to i17
528; CHECK-NEXT:    ret i17 [[SHR]]
529;
530  %sub = sub nsw i17 %x, %y
531  %shr = ashr i17 %sub, 16
532  ret i17 %shr
533}
534
535; negative test - must shift sign-bit
536
537define i17 @ashr_sub_wrong_amount(i17 %x, i17 %y) {
538; CHECK-LABEL: @ashr_sub_wrong_amount(
539; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i17 [[X:%.*]], [[Y:%.*]]
540; CHECK-NEXT:    [[SHR:%.*]] = ashr i17 [[SUB]], 15
541; CHECK-NEXT:    ret i17 [[SHR]]
542;
543  %sub = sub nsw i17 %x, %y
544  %shr = ashr i17 %sub, 15
545  ret i17 %shr
546}
547
548; negative test - must have nsw
549
550define i32 @ashr_sub(i32 %x, i32 %y) {
551; CHECK-LABEL: @ashr_sub(
552; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
553; CHECK-NEXT:    [[SHR:%.*]] = ashr i32 [[SUB]], 31
554; CHECK-NEXT:    ret i32 [[SHR]]
555;
556  %sub = sub i32 %x, %y
557  %shr = ashr i32 %sub, 31
558  ret i32 %shr
559}
560
561; negative test - one-use
562
563define i32 @ashr_sub_nsw_extra_use(i32 %x, i32 %y, ptr %p) {
564; CHECK-LABEL: @ashr_sub_nsw_extra_use(
565; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
566; CHECK-NEXT:    store i32 [[SUB]], ptr [[P:%.*]], align 4
567; CHECK-NEXT:    [[SHR:%.*]] = ashr i32 [[SUB]], 31
568; CHECK-NEXT:    ret i32 [[SHR]]
569;
570  %sub = sub nsw i32 %x, %y
571  store i32 %sub, ptr %p
572  %shr = ashr i32 %sub, 31
573  ret i32 %shr
574}
575
576define <3 x i43> @ashr_sub_nsw_splat(<3 x i43> %x, <3 x i43> %y) {
577; CHECK-LABEL: @ashr_sub_nsw_splat(
578; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <3 x i43> [[X:%.*]], [[Y:%.*]]
579; CHECK-NEXT:    [[SHR:%.*]] = sext <3 x i1> [[TMP1]] to <3 x i43>
580; CHECK-NEXT:    ret <3 x i43> [[SHR]]
581;
582  %sub = sub nsw <3 x i43> %x, %y
583  %shr = ashr <3 x i43> %sub, <i43 42, i43 42, i43 42>
584  ret <3 x i43> %shr
585}
586
587define <3 x i43> @ashr_sub_nsw_splat_poison(<3 x i43> %x, <3 x i43> %y) {
588; CHECK-LABEL: @ashr_sub_nsw_splat_poison(
589; CHECK-NEXT:    [[SUB:%.*]] = sub nsw <3 x i43> [[X:%.*]], [[Y:%.*]]
590; CHECK-NEXT:    [[SHR:%.*]] = ashr <3 x i43> [[SUB]], <i43 42, i43 poison, i43 42>
591; CHECK-NEXT:    ret <3 x i43> [[SHR]]
592;
593  %sub = sub nsw <3 x i43> %x, %y
594  %shr = ashr <3 x i43> %sub, <i43 42, i43 poison, i43 42>
595  ret <3 x i43> %shr
596}
597
598define i8 @ashr_known_pos_exact(i8 %x, i8 %y) {
599; CHECK-LABEL: @ashr_known_pos_exact(
600; CHECK-NEXT:    [[P:%.*]] = and i8 [[X:%.*]], 127
601; CHECK-NEXT:    [[R:%.*]] = lshr exact i8 [[P]], [[Y:%.*]]
602; CHECK-NEXT:    ret i8 [[R]]
603;
604  %p = and i8 %x, 127
605  %r = ashr exact i8 %p, %y
606  ret i8 %r
607}
608
609define <2 x i8> @ashr_known_pos_exact_vec(<2 x i8> %x, <2 x i8> %y) {
610; CHECK-LABEL: @ashr_known_pos_exact_vec(
611; CHECK-NEXT:    [[P:%.*]] = mul nsw <2 x i8> [[X:%.*]], [[X]]
612; CHECK-NEXT:    [[R:%.*]] = lshr exact <2 x i8> [[P]], [[Y:%.*]]
613; CHECK-NEXT:    ret <2 x i8> [[R]]
614;
615  %p = mul nsw <2 x i8> %x, %x
616  %r = ashr exact <2 x i8> %p, %y
617  ret <2 x i8> %r
618}
619
620define i32 @lshr_mul_times_3_div_2(i32 %0) {
621; CHECK-LABEL: @lshr_mul_times_3_div_2(
622; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP0:%.*]], 1
623; CHECK-NEXT:    [[LSHR:%.*]] = add nuw nsw i32 [[TMP0]], [[TMP2]]
624; CHECK-NEXT:    ret i32 [[LSHR]]
625;
626  %mul = mul nsw nuw i32 %0, 3
627  %lshr = lshr i32 %mul, 1
628  ret i32 %lshr
629}
630
631define i32 @lshr_mul_times_3_div_2_exact(i32 %x) {
632; CHECK-LABEL: @lshr_mul_times_3_div_2_exact(
633; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 1
634; CHECK-NEXT:    [[LSHR:%.*]] = add nsw i32 [[X]], [[TMP1]]
635; CHECK-NEXT:    ret i32 [[LSHR]]
636;
637  %mul = mul nsw i32 %x, 3
638  %lshr = lshr exact i32 %mul, 1
639  ret i32 %lshr
640}
641
642; Negative test
643
644define i32 @lshr_mul_times_3_div_2_no_flags(i32 %0) {
645; CHECK-LABEL: @lshr_mul_times_3_div_2_no_flags(
646; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 3
647; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 [[MUL]], 1
648; CHECK-NEXT:    ret i32 [[LSHR]]
649;
650  %mul = mul i32 %0, 3
651  %lshr = lshr i32 %mul, 1
652  ret i32 %lshr
653}
654
655; Negative test
656
657define i32 @mul_times_3_div_2_multiuse_lshr(i32 %x) {
658; CHECK-LABEL: @mul_times_3_div_2_multiuse_lshr(
659; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[X:%.*]], 3
660; CHECK-NEXT:    [[RES:%.*]] = lshr i32 [[MUL]], 1
661; CHECK-NEXT:    call void @use(i32 [[MUL]])
662; CHECK-NEXT:    ret i32 [[RES]]
663;
664  %mul = mul nuw i32 %x, 3
665  %res = lshr i32 %mul, 1
666  call void @use(i32 %mul)
667  ret i32 %res
668}
669
670define i32 @lshr_mul_times_3_div_2_exact_2(i32 %x) {
671; CHECK-LABEL: @lshr_mul_times_3_div_2_exact_2(
672; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 1
673; CHECK-NEXT:    [[LSHR:%.*]] = add nuw i32 [[X]], [[TMP1]]
674; CHECK-NEXT:    ret i32 [[LSHR]]
675;
676  %mul = mul nuw i32 %x, 3
677  %lshr = lshr exact i32 %mul, 1
678  ret i32 %lshr
679}
680
681define i32 @lshr_mul_times_5_div_4(i32 %0) {
682; CHECK-LABEL: @lshr_mul_times_5_div_4(
683; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP0:%.*]], 2
684; CHECK-NEXT:    [[LSHR:%.*]] = add nuw nsw i32 [[TMP0]], [[TMP2]]
685; CHECK-NEXT:    ret i32 [[LSHR]]
686;
687  %mul = mul nsw nuw i32 %0, 5
688  %lshr = lshr i32 %mul, 2
689  ret i32 %lshr
690}
691
692define i32 @lshr_mul_times_5_div_4_exact(i32 %x) {
693; CHECK-LABEL: @lshr_mul_times_5_div_4_exact(
694; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 2
695; CHECK-NEXT:    [[LSHR:%.*]] = add nsw i32 [[X]], [[TMP1]]
696; CHECK-NEXT:    ret i32 [[LSHR]]
697;
698  %mul = mul nsw i32 %x, 5
699  %lshr = lshr exact i32 %mul, 2
700  ret i32 %lshr
701}
702
703; Negative test
704
705define i32 @lshr_mul_times_5_div_4_no_flags(i32 %0) {
706; CHECK-LABEL: @lshr_mul_times_5_div_4_no_flags(
707; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 5
708; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 [[MUL]], 2
709; CHECK-NEXT:    ret i32 [[LSHR]]
710;
711  %mul = mul i32 %0, 5
712  %lshr = lshr i32 %mul, 2
713  ret i32 %lshr
714}
715
716; Negative test
717
718define i32 @mul_times_5_div_4_multiuse_lshr(i32 %x) {
719; CHECK-LABEL: @mul_times_5_div_4_multiuse_lshr(
720; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[X:%.*]], 5
721; CHECK-NEXT:    [[RES:%.*]] = lshr i32 [[MUL]], 2
722; CHECK-NEXT:    call void @use(i32 [[MUL]])
723; CHECK-NEXT:    ret i32 [[RES]]
724;
725  %mul = mul nuw i32 %x, 5
726  %res = lshr i32 %mul, 2
727  call void @use(i32 %mul)
728  ret i32 %res
729}
730
731define i32 @lshr_mul_times_5_div_4_exact_2(i32 %x) {
732; CHECK-LABEL: @lshr_mul_times_5_div_4_exact_2(
733; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 2
734; CHECK-NEXT:    [[LSHR:%.*]] = add nuw i32 [[X]], [[TMP1]]
735; CHECK-NEXT:    ret i32 [[LSHR]]
736;
737  %mul = mul nuw i32 %x, 5
738  %lshr = lshr exact i32 %mul, 2
739  ret i32 %lshr
740}
741
742define i32 @ashr_mul_times_3_div_2(i32 %0) {
743; CHECK-LABEL: @ashr_mul_times_3_div_2(
744; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP0:%.*]], 1
745; CHECK-NEXT:    [[ASHR:%.*]] = add nuw nsw i32 [[TMP0]], [[TMP2]]
746; CHECK-NEXT:    ret i32 [[ASHR]]
747;
748  %mul = mul nuw nsw i32 %0, 3
749  %ashr = ashr i32 %mul, 1
750  ret i32 %ashr
751}
752
753define i32 @ashr_mul_times_3_div_2_exact(i32 %x) {
754; CHECK-LABEL: @ashr_mul_times_3_div_2_exact(
755; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 1
756; CHECK-NEXT:    [[ASHR:%.*]] = add nsw i32 [[X]], [[TMP1]]
757; CHECK-NEXT:    ret i32 [[ASHR]]
758;
759  %mul = mul nsw i32 %x, 3
760  %ashr = ashr exact i32 %mul, 1
761  ret i32 %ashr
762}
763
764; Negative test
765
766define i32 @ashr_mul_times_3_div_2_no_flags(i32 %0) {
767; CHECK-LABEL: @ashr_mul_times_3_div_2_no_flags(
768; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 3
769; CHECK-NEXT:    [[ASHR:%.*]] = ashr i32 [[MUL]], 1
770; CHECK-NEXT:    ret i32 [[ASHR]]
771;
772  %mul = mul i32 %0, 3
773  %ashr = ashr i32 %mul, 1
774  ret i32 %ashr
775}
776
777; Negative test
778
779define i32 @ashr_mul_times_3_div_2_no_nsw(i32 %0) {
780; CHECK-LABEL: @ashr_mul_times_3_div_2_no_nsw(
781; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[TMP0:%.*]], 3
782; CHECK-NEXT:    [[ASHR:%.*]] = ashr i32 [[MUL]], 1
783; CHECK-NEXT:    ret i32 [[ASHR]]
784;
785  %mul = mul nuw i32 %0, 3
786  %ashr = ashr i32 %mul, 1
787  ret i32 %ashr
788}
789
790; Negative test
791
792define i32 @mul_times_3_div_2_multiuse_ashr(i32 %x) {
793; CHECK-LABEL: @mul_times_3_div_2_multiuse_ashr(
794; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 3
795; CHECK-NEXT:    [[RES:%.*]] = ashr i32 [[MUL]], 1
796; CHECK-NEXT:    call void @use(i32 [[MUL]])
797; CHECK-NEXT:    ret i32 [[RES]]
798;
799  %mul = mul nsw i32 %x, 3
800  %res = ashr i32 %mul, 1
801  call void @use(i32 %mul)
802  ret i32 %res
803}
804
805define i32 @ashr_mul_times_3_div_2_exact_2(i32 %x) {
806; CHECK-LABEL: @ashr_mul_times_3_div_2_exact_2(
807; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 1
808; CHECK-NEXT:    [[ASHR:%.*]] = add nsw i32 [[X]], [[TMP1]]
809; CHECK-NEXT:    ret i32 [[ASHR]]
810;
811  %mul = mul nsw i32 %x, 3
812  %ashr = ashr exact i32 %mul, 1
813  ret i32 %ashr
814}
815
816define i32 @ashr_mul_times_5_div_4(i32 %0) {
817; CHECK-LABEL: @ashr_mul_times_5_div_4(
818; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[TMP0:%.*]], 2
819; CHECK-NEXT:    [[ASHR:%.*]] = add nuw nsw i32 [[TMP0]], [[TMP2]]
820; CHECK-NEXT:    ret i32 [[ASHR]]
821;
822  %mul = mul nuw nsw i32 %0, 5
823  %ashr = ashr i32 %mul, 2
824  ret i32 %ashr
825}
826
827define i32 @ashr_mul_times_5_div_4_exact(i32 %x) {
828; CHECK-LABEL: @ashr_mul_times_5_div_4_exact(
829; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 2
830; CHECK-NEXT:    [[ASHR:%.*]] = add nsw i32 [[X]], [[TMP1]]
831; CHECK-NEXT:    ret i32 [[ASHR]]
832;
833  %mul = mul nsw i32 %x, 5
834  %ashr = ashr exact i32 %mul, 2
835  ret i32 %ashr
836}
837
838; Negative test
839
840define i32 @ashr_mul_times_5_div_4_no_flags(i32 %0) {
841; CHECK-LABEL: @ashr_mul_times_5_div_4_no_flags(
842; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TMP0:%.*]], 5
843; CHECK-NEXT:    [[ASHR:%.*]] = ashr i32 [[MUL]], 2
844; CHECK-NEXT:    ret i32 [[ASHR]]
845;
846  %mul = mul i32 %0, 5
847  %ashr = ashr i32 %mul, 2
848  ret i32 %ashr
849}
850
851; Negative test
852
853define i32 @mul_times_5_div_4_multiuse_ashr(i32 %x) {
854; CHECK-LABEL: @mul_times_5_div_4_multiuse_ashr(
855; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 5
856; CHECK-NEXT:    [[RES:%.*]] = ashr i32 [[MUL]], 2
857; CHECK-NEXT:    call void @use(i32 [[MUL]])
858; CHECK-NEXT:    ret i32 [[RES]]
859;
860  %mul = mul nsw i32 %x, 5
861  %res = ashr i32 %mul, 2
862  call void @use(i32 %mul)
863  ret i32 %res
864}
865
866define i32 @ashr_mul_times_5_div_4_exact_2(i32 %x) {
867; CHECK-LABEL: @ashr_mul_times_5_div_4_exact_2(
868; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i32 [[X:%.*]], 2
869; CHECK-NEXT:    [[ASHR:%.*]] = add nsw i32 [[X]], [[TMP1]]
870; CHECK-NEXT:    ret i32 [[ASHR]]
871;
872  %mul = mul nsw i32 %x, 5
873  %ashr = ashr exact i32 %mul, 2
874  ret i32 %ashr
875}
876
877
878define i32 @lsb_mask_sign_zext(i32 %x) {
879; CHECK-LABEL: @lsb_mask_sign_zext(
880; CHECK-NEXT:  entry:
881; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i32 [[X:%.*]], 0
882; CHECK-NEXT:    [[SHR:%.*]] = zext i1 [[TMP0]] to i32
883; CHECK-NEXT:    ret i32 [[SHR]]
884;
885entry:
886  %sub = add i32 %x, -1
887  %not = xor i32 %x, -1
888  %and = and i32 %sub, %not
889  %shr = lshr i32 %and, 31
890  ret i32 %shr
891}
892
893define i32 @lsb_mask_sign_zext_commuted(i32 %x) {
894; CHECK-LABEL: @lsb_mask_sign_zext_commuted(
895; CHECK-NEXT:  entry:
896; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i32 [[X:%.*]], 0
897; CHECK-NEXT:    [[SHR:%.*]] = zext i1 [[TMP0]] to i32
898; CHECK-NEXT:    ret i32 [[SHR]]
899;
900entry:
901  %sub = add i32 %x, -1
902  %not = xor i32 %x, -1
903  %and = and i32 %not, %sub
904  %shr = lshr i32 %and, 31
905  ret i32 %shr
906}
907
908; Negative tests
909
910define i32 @lsb_mask_sign_zext_wrong_cst1(i32 %x) {
911; CHECK-LABEL: @lsb_mask_sign_zext_wrong_cst1(
912; CHECK-NEXT:  entry:
913; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -2
914; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[X]], -1
915; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[NOT]]
916; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[AND]], 31
917; CHECK-NEXT:    ret i32 [[SHR]]
918;
919entry:
920  %sub = add i32 %x, -2
921  %not = xor i32 %x, -1
922  %and = and i32 %sub, %not
923  %shr = lshr i32 %and, 31
924  ret i32 %shr
925}
926
927define i32 @lsb_mask_sign_zext_wrong_cst2(i32 %x) {
928; CHECK-LABEL: @lsb_mask_sign_zext_wrong_cst2(
929; CHECK-NEXT:  entry:
930; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -1
931; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[X]]
932; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[AND]], 31
933; CHECK-NEXT:    ret i32 [[SHR]]
934;
935entry:
936  %sub = add i32 %x, -1
937  %not = xor i32 %x, 2
938  %and = and i32 %sub, %not
939  %shr = lshr i32 %and, 31
940  ret i32 %shr
941}
942
943define i32 @lsb_mask_sign_zext_wrong_cst3(i32 %x) {
944; CHECK-LABEL: @lsb_mask_sign_zext_wrong_cst3(
945; CHECK-NEXT:  entry:
946; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -1
947; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[X]], -1
948; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[NOT]]
949; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[AND]], 30
950; CHECK-NEXT:    ret i32 [[SHR]]
951;
952entry:
953  %sub = add i32 %x, -1
954  %not = xor i32 %x, -1
955  %and = and i32 %sub, %not
956  %shr = lshr i32 %and, 30
957  ret i32 %shr
958}
959
960define i32 @lsb_mask_sign_zext_multiuse(i32 %x) {
961; CHECK-LABEL: @lsb_mask_sign_zext_multiuse(
962; CHECK-NEXT:  entry:
963; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -1
964; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[X]], -1
965; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[NOT]]
966; CHECK-NEXT:    call void @use(i32 [[AND]])
967; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[AND]], 31
968; CHECK-NEXT:    ret i32 [[SHR]]
969;
970entry:
971  %sub = add i32 %x, -1
972  %not = xor i32 %x, -1
973  %and = and i32 %sub, %not
974  call void @use(i32 %and)
975  %shr = lshr i32 %and, 31
976  ret i32 %shr
977}
978
979define i32 @lsb_mask_sign_sext(i32 %x) {
980; CHECK-LABEL: @lsb_mask_sign_sext(
981; CHECK-NEXT:  entry:
982; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i32 [[X:%.*]], 0
983; CHECK-NEXT:    [[SHR:%.*]] = sext i1 [[TMP0]] to i32
984; CHECK-NEXT:    ret i32 [[SHR]]
985;
986entry:
987  %sub = add i32 %x, -1
988  %not = xor i32 %x, -1
989  %and = and i32 %sub, %not
990  %shr = ashr i32 %and, 31
991  ret i32 %shr
992}
993
994define i32 @lsb_mask_sign_sext_commuted(i32 %x) {
995; CHECK-LABEL: @lsb_mask_sign_sext_commuted(
996; CHECK-NEXT:  entry:
997; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i32 [[X:%.*]], 0
998; CHECK-NEXT:    [[SHR:%.*]] = sext i1 [[TMP0]] to i32
999; CHECK-NEXT:    ret i32 [[SHR]]
1000;
1001entry:
1002  %sub = add i32 %x, -1
1003  %not = xor i32 %x, -1
1004  %and = and i32 %not, %sub
1005  %shr = ashr i32 %and, 31
1006  ret i32 %shr
1007}
1008
1009; Negative tests
1010
1011define i32 @lsb_mask_sign_sext_wrong_cst1(i32 %x) {
1012; CHECK-LABEL: @lsb_mask_sign_sext_wrong_cst1(
1013; CHECK-NEXT:  entry:
1014; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -2
1015; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[X]], -1
1016; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[NOT]]
1017; CHECK-NEXT:    [[SHR:%.*]] = ashr i32 [[AND]], 31
1018; CHECK-NEXT:    ret i32 [[SHR]]
1019;
1020entry:
1021  %sub = add i32 %x, -2
1022  %not = xor i32 %x, -1
1023  %and = and i32 %sub, %not
1024  %shr = ashr i32 %and, 31
1025  ret i32 %shr
1026}
1027
1028define i32 @lsb_mask_sign_sext_wrong_cst2(i32 %x) {
1029; CHECK-LABEL: @lsb_mask_sign_sext_wrong_cst2(
1030; CHECK-NEXT:  entry:
1031; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -1
1032; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[X]]
1033; CHECK-NEXT:    [[SHR:%.*]] = ashr i32 [[AND]], 31
1034; CHECK-NEXT:    ret i32 [[SHR]]
1035;
1036entry:
1037  %sub = add i32 %x, -1
1038  %not = xor i32 %x, 2
1039  %and = and i32 %sub, %not
1040  %shr = ashr i32 %and, 31
1041  ret i32 %shr
1042}
1043
1044define i32 @lsb_mask_sign_sext_wrong_cst3(i32 %x) {
1045; CHECK-LABEL: @lsb_mask_sign_sext_wrong_cst3(
1046; CHECK-NEXT:  entry:
1047; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -1
1048; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[X]], -1
1049; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[NOT]]
1050; CHECK-NEXT:    [[SHR:%.*]] = ashr i32 [[AND]], 30
1051; CHECK-NEXT:    ret i32 [[SHR]]
1052;
1053entry:
1054  %sub = add i32 %x, -1
1055  %not = xor i32 %x, -1
1056  %and = and i32 %sub, %not
1057  %shr = ashr i32 %and, 30
1058  ret i32 %shr
1059}
1060
1061define i32 @lsb_mask_sign_sext_multiuse(i32 %x) {
1062; CHECK-LABEL: @lsb_mask_sign_sext_multiuse(
1063; CHECK-NEXT:  entry:
1064; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[X:%.*]], -1
1065; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[X]], -1
1066; CHECK-NEXT:    [[AND:%.*]] = and i32 [[SUB]], [[NOT]]
1067; CHECK-NEXT:    call void @use(i32 [[AND]])
1068; CHECK-NEXT:    [[SHR:%.*]] = ashr i32 [[AND]], 31
1069; CHECK-NEXT:    ret i32 [[SHR]]
1070;
1071entry:
1072  %sub = add i32 %x, -1
1073  %not = xor i32 %x, -1
1074  %and = and i32 %sub, %not
1075  call void @use(i32 %and)
1076  %shr = ashr i32 %and, 31
1077  ret i32 %shr
1078}
1079
1080declare void @use(i32)
1081