1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -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:    [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]
7; CHECK-NEXT:    ret i32 [[CMP1]]
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:    [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]
19; CHECK-NEXT:    ret i32 [[CMP1]]
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:    [[CMP1:%.*]] = ashr exact i32 [[X:%.*]], [[Y:%.*]]
31; CHECK-NEXT:    ret i32 [[CMP1]]
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:    [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]
43; CHECK-NEXT:    ret i32 [[CMP1]]
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 <2 x i32> @ashr_lshr_splat_vec(<2 x i32> %x, <2 x i32> %y) {
65; CHECK-LABEL: @ashr_lshr_splat_vec(
66; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
67; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
68;
69  %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
70  %l = lshr <2 x i32> %x, %y
71  %r = ashr <2 x i32> %x, %y
72  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r
73  ret <2 x i32> %ret
74}
75
76define <2 x i32> @ashr_lshr_splat_vec2(<2 x i32> %x, <2 x i32> %y) {
77; CHECK-LABEL: @ashr_lshr_splat_vec2(
78; CHECK-NEXT:    [[CMP1:%.*]] = ashr exact <2 x i32> [[X:%.*]], [[Y:%.*]]
79; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
80;
81  %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
82  %l = lshr exact <2 x i32> %x, %y
83  %r = ashr exact <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_vec3(<2 x i32> %x, <2 x i32> %y) {
89; CHECK-LABEL: @ashr_lshr_splat_vec3(
90; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
91; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
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 <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_vec4(<2 x i32> %x, <2 x i32> %y) {
101; CHECK-LABEL: @ashr_lshr_splat_vec4(
102; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
103; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
104;
105  %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1>
106  %l = lshr <2 x i32> %x, %y
107  %r = ashr exact <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_nonsplat_vec(<2 x i32> %x, <2 x i32> %y) {
113; CHECK-LABEL: @ashr_lshr_nonsplat_vec(
114; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
115; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
116;
117  %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 1>
118  %l = lshr <2 x i32> %x, %y
119  %r = ashr <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_vec2(<2 x i32> %x, <2 x i32> %y) {
125; CHECK-LABEL: @ashr_lshr_nonsplat_vec2(
126; CHECK-NEXT:    [[CMP1:%.*]] = ashr exact <2 x i32> [[X:%.*]], [[Y:%.*]]
127; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
128;
129  %cmp = icmp sgt <2 x i32> %x, <i32 2, i32 4>
130  %l = lshr exact <2 x i32> %x, %y
131  %r = ashr exact <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_vec3(<2 x i32> %x, <2 x i32> %y) {
137; CHECK-LABEL: @ashr_lshr_nonsplat_vec3(
138; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
139; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
140;
141  %cmp = icmp sgt <2 x i32> %x, <i32 5, i32 6>
142  %l = lshr exact <2 x i32> %x, %y
143  %r = ashr <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_vec4(<2 x i32> %x, <2 x i32> %y) {
149; CHECK-LABEL: @ashr_lshr_nonsplat_vec4(
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 8, i32 7>
154  %l = lshr <2 x i32> %x, %y
155  %r = ashr exact <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 i32 @ashr_lshr_cst(i32 %x, i32 %y) {
161; CHECK-LABEL: @ashr_lshr_cst(
162; CHECK-NEXT:    [[CMP1:%.*]] = ashr i32 [[X:%.*]], 8
163; CHECK-NEXT:    ret i32 [[CMP1]]
164;
165  %cmp = icmp slt i32 %x, 1
166  %l = lshr i32 %x, 8
167  %r = ashr exact i32 %x, 8
168  %ret = select i1 %cmp, i32 %r, i32 %l
169  ret i32 %ret
170}
171
172define i32 @ashr_lshr_cst2(i32 %x, i32 %y) {
173; CHECK-LABEL: @ashr_lshr_cst2(
174; CHECK-NEXT:    [[CMP1:%.*]] = ashr i32 [[X:%.*]], 8
175; CHECK-NEXT:    ret i32 [[CMP1]]
176;
177  %cmp = icmp sgt i32 %x, -1
178  %l = lshr i32 %x, 8
179  %r = ashr exact i32 %x, 8
180  %ret = select i1 %cmp, i32 %l, i32 %r
181  ret i32 %ret
182}
183
184define i32 @ashr_lshr_inv(i32 %x, i32 %y) {
185; CHECK-LABEL: @ashr_lshr_inv(
186; CHECK-NEXT:    [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]
187; CHECK-NEXT:    ret i32 [[CMP1]]
188;
189  %cmp = icmp slt i32 %x, 1
190  %l = lshr i32 %x, %y
191  %r = ashr exact i32 %x, %y
192  %ret = select i1 %cmp, i32 %r, i32 %l
193  ret i32 %ret
194}
195
196define i32 @ashr_lshr_inv2(i32 %x, i32 %y) {
197; CHECK-LABEL: @ashr_lshr_inv2(
198; CHECK-NEXT:    [[CMP1:%.*]] = ashr i32 [[X:%.*]], [[Y:%.*]]
199; CHECK-NEXT:    ret i32 [[CMP1]]
200;
201  %cmp = icmp slt i32 %x, 7
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 <2 x i32> @ashr_lshr_inv_splat_vec(<2 x i32> %x, <2 x i32> %y) {
209; CHECK-LABEL: @ashr_lshr_inv_splat_vec(
210; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
211; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
212;
213  %cmp = icmp slt <2 x i32> %x, <i32 1, i32 1>
214  %l = lshr <2 x i32> %x, %y
215  %r = ashr exact <2 x i32> %x, %y
216  %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l
217  ret <2 x i32> %ret
218}
219
220define <2 x i32> @ashr_lshr_inv_nonsplat_vec(<2 x i32> %x, <2 x i32> %y) {
221; CHECK-LABEL: @ashr_lshr_inv_nonsplat_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 4, i32 5>
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_vec_undef(<2 x i32> %x, <2 x i32> %y) {
233; CHECK-LABEL: @ashr_lshr_vec_undef(
234; CHECK-NEXT:    [[CMP1:%.*]] = ashr <2 x i32> [[X:%.*]], [[Y:%.*]]
235; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
236;
237  %cmp = icmp sgt <2 x i32> %x, <i32 undef, i32 -1>
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> %l, <2 x i32> %r
241  ret <2 x i32> %ret
242}
243
244define <2 x i32> @ashr_lshr_vec_undef2(<2 x i32> %x, <2 x i32> %y) {
245; CHECK-LABEL: @ashr_lshr_vec_undef2(
246; CHECK-NEXT:    [[CMP1:%.*]] = ashr exact <2 x i32> [[X:%.*]], [[Y:%.*]]
247; CHECK-NEXT:    ret <2 x i32> [[CMP1]]
248;
249  %cmp = icmp slt <2 x i32> %x, <i32 1, i32 undef>
250  %l = lshr exact <2 x i32> %x, %y
251  %r = ashr exact <2 x i32> %x, %y
252  %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l
253  ret <2 x i32> %ret
254}
255
256; Negative tests
257
258define i32 @ashr_lshr_wrong_cst(i32 %x, i32 %y) {
259; CHECK-LABEL: @ashr_lshr_wrong_cst(
260; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -2
261; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]
262; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 [[X]], [[Y]]
263; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]]
264; CHECK-NEXT:    ret i32 [[RET]]
265;
266  %cmp = icmp sgt i32 %x, -2
267  %l = lshr i32 %x, %y
268  %r = ashr exact i32 %x, %y
269  %ret = select i1 %cmp, i32 %l, i32 %r
270  ret i32 %ret
271}
272
273define i32 @ashr_lshr_wrong_cst2(i32 %x, i32 %y) {
274; CHECK-LABEL: @ashr_lshr_wrong_cst2(
275; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], -1
276; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]
277; CHECK-NEXT:    [[R:%.*]] = ashr exact i32 [[X]], [[Y]]
278; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[R]], i32 [[L]]
279; CHECK-NEXT:    ret i32 [[RET]]
280;
281  %cmp = icmp slt i32 %x, -1
282  %l = lshr i32 %x, %y
283  %r = ashr exact i32 %x, %y
284  %ret = select i1 %cmp, i32 %r, i32 %l
285  ret i32 %ret
286}
287
288define i32 @ashr_lshr_wrong_cond(i32 %x, i32 %y) {
289; CHECK-LABEL: @ashr_lshr_wrong_cond(
290; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -2
291; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]
292; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Y]]
293; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]]
294; CHECK-NEXT:    ret i32 [[RET]]
295;
296  %cmp = icmp sge i32 %x, -1
297  %l = lshr i32 %x, %y
298  %r = ashr i32 %x, %y
299  %ret = select i1 %cmp, i32 %l, i32 %r
300  ret i32 %ret
301}
302
303define i32 @ashr_lshr_shift_wrong_pred(i32 %x, i32 %y, i32 %z) {
304; CHECK-LABEL: @ashr_lshr_shift_wrong_pred(
305; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
306; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]
307; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Y]]
308; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]]
309; CHECK-NEXT:    ret i32 [[RET]]
310;
311  %cmp = icmp sle i32 %x, 0
312  %l = lshr i32 %x, %y
313  %r = ashr i32 %x, %y
314  %ret = select i1 %cmp, i32 %l, i32 %r
315  ret i32 %ret
316}
317
318define i32 @ashr_lshr_shift_wrong_pred2(i32 %x, i32 %y, i32 %z) {
319; CHECK-LABEL: @ashr_lshr_shift_wrong_pred2(
320; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[Z:%.*]], -1
321; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X:%.*]], [[Y:%.*]]
322; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Y]]
323; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]]
324; CHECK-NEXT:    ret i32 [[RET]]
325;
326  %cmp = icmp sge i32 %z, 0
327  %l = lshr i32 %x, %y
328  %r = ashr i32 %x, %y
329  %ret = select i1 %cmp, i32 %l, i32 %r
330  ret i32 %ret
331}
332
333define i32 @ashr_lshr_wrong_operands(i32 %x, i32 %y) {
334; CHECK-LABEL: @ashr_lshr_wrong_operands(
335; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1
336; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]
337; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Y]]
338; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[R]], i32 [[L]]
339; CHECK-NEXT:    ret i32 [[RET]]
340;
341  %cmp = icmp sge i32 %x, 0
342  %l = lshr i32 %x, %y
343  %r = ashr i32 %x, %y
344  %ret = select i1 %cmp, i32 %r, i32 %l
345  ret i32 %ret
346}
347
348define i32 @ashr_lshr_no_ashr(i32 %x, i32 %y) {
349; CHECK-LABEL: @ashr_lshr_no_ashr(
350; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1
351; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]
352; CHECK-NEXT:    [[R:%.*]] = xor i32 [[X]], [[Y]]
353; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]]
354; CHECK-NEXT:    ret i32 [[RET]]
355;
356  %cmp = icmp sge i32 %x, 0
357  %l = lshr i32 %x, %y
358  %r = xor i32 %x, %y
359  %ret = select i1 %cmp, i32 %l, i32 %r
360  ret i32 %ret
361}
362
363define i32 @ashr_lshr_shift_amt_mismatch(i32 %x, i32 %y, i32 %z) {
364; CHECK-LABEL: @ashr_lshr_shift_amt_mismatch(
365; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1
366; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]
367; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Z:%.*]]
368; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]]
369; CHECK-NEXT:    ret i32 [[RET]]
370;
371  %cmp = icmp sge i32 %x, 0
372  %l = lshr i32 %x, %y
373  %r = ashr i32 %x, %z
374  %ret = select i1 %cmp, i32 %l, i32 %r
375  ret i32 %ret
376}
377
378define i32 @ashr_lshr_shift_base_mismatch(i32 %x, i32 %y, i32 %z) {
379; CHECK-LABEL: @ashr_lshr_shift_base_mismatch(
380; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1
381; CHECK-NEXT:    [[L:%.*]] = lshr i32 [[X]], [[Y:%.*]]
382; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[Z:%.*]], [[Y]]
383; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]]
384; CHECK-NEXT:    ret i32 [[RET]]
385;
386  %cmp = icmp sge i32 %x, 0
387  %l = lshr i32 %x, %y
388  %r = ashr i32 %z, %y
389  %ret = select i1 %cmp, i32 %l, i32 %r
390  ret i32 %ret
391}
392
393define i32 @ashr_lshr_no_lshr(i32 %x, i32 %y) {
394; CHECK-LABEL: @ashr_lshr_no_lshr(
395; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1
396; CHECK-NEXT:    [[L:%.*]] = add i32 [[X]], [[Y:%.*]]
397; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X]], [[Y]]
398; CHECK-NEXT:    [[RET:%.*]] = select i1 [[CMP]], i32 [[L]], i32 [[R]]
399; CHECK-NEXT:    ret i32 [[RET]]
400;
401  %cmp = icmp sge i32 %x, 0
402  %l = add i32 %x, %y
403  %r = ashr i32 %x, %y
404  %ret = select i1 %cmp, i32 %l, i32 %r
405  ret i32 %ret
406}
407
408define <2 x i32> @ashr_lshr_vec_wrong_pred(<2 x i32> %x, <2 x i32> %y) {
409; CHECK-LABEL: @ashr_lshr_vec_wrong_pred(
410; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 1, i32 1>
411; CHECK-NEXT:    [[L:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]]
412; CHECK-NEXT:    [[R:%.*]] = ashr <2 x i32> [[X]], [[Y]]
413; CHECK-NEXT:    [[RET:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[L]], <2 x i32> [[R]]
414; CHECK-NEXT:    ret <2 x i32> [[RET]]
415;
416  %cmp = icmp sle <2 x i32> %x, zeroinitializer
417  %l = lshr <2 x i32> %x, %y
418  %r = ashr <2 x i32> %x, %y
419  %ret = select <2 x i1> %cmp, <2 x i32> %l, <2 x i32> %r
420  ret <2 x i32> %ret
421}
422
423define <2 x i32> @ashr_lshr_inv_vec_wrong_pred(<2 x i32> %x, <2 x i32> %y) {
424; CHECK-LABEL: @ashr_lshr_inv_vec_wrong_pred(
425; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 -1, i32 -1>
426; CHECK-NEXT:    [[L:%.*]] = lshr <2 x i32> [[X]], [[Y:%.*]]
427; CHECK-NEXT:    [[R:%.*]] = ashr <2 x i32> [[X]], [[Y]]
428; CHECK-NEXT:    [[RET:%.*]] = select <2 x i1> [[CMP]], <2 x i32> [[R]], <2 x i32> [[L]]
429; CHECK-NEXT:    ret <2 x i32> [[RET]]
430;
431  %cmp = icmp sge <2 x i32> %x, zeroinitializer
432  %l = lshr <2 x i32> %x, %y
433  %r = ashr <2 x i32> %x, %y
434  %ret = select <2 x i1> %cmp, <2 x i32> %r, <2 x i32> %l
435  ret <2 x i32> %ret
436}
437
438define i32 @lshr_sub_nsw(i32 %x, i32 %y) {
439; CHECK-LABEL: @lshr_sub_nsw(
440; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
441; CHECK-NEXT:    [[SHR:%.*]] = zext i1 [[TMP1]] to i32
442; CHECK-NEXT:    ret i32 [[SHR]]
443;
444  %sub = sub nsw i32 %x, %y
445  %shr = lshr i32 %sub, 31
446  ret i32 %shr
447}
448
449; negative test - must shift sign-bit
450
451define i32 @lshr_sub_wrong_amount(i32 %x, i32 %y) {
452; CHECK-LABEL: @lshr_sub_wrong_amount(
453; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
454; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[SUB]], 30
455; CHECK-NEXT:    ret i32 [[SHR]]
456;
457  %sub = sub nsw i32 %x, %y
458  %shr = lshr i32 %sub, 30
459  ret i32 %shr
460}
461
462; negative test - must have nsw
463
464define i32 @lshr_sub(i32 %x, i32 %y) {
465; CHECK-LABEL: @lshr_sub(
466; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
467; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[SUB]], 31
468; CHECK-NEXT:    ret i32 [[SHR]]
469;
470  %sub = sub i32 %x, %y
471  %shr = lshr i32 %sub, 31
472  ret i32 %shr
473}
474
475; negative test - one-use
476
477define i32 @lshr_sub_nsw_extra_use(i32 %x, i32 %y, i32* %p) {
478; CHECK-LABEL: @lshr_sub_nsw_extra_use(
479; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
480; CHECK-NEXT:    store i32 [[SUB]], i32* [[P:%.*]], align 4
481; CHECK-NEXT:    [[SHR:%.*]] = lshr i32 [[SUB]], 31
482; CHECK-NEXT:    ret i32 [[SHR]]
483;
484  %sub = sub nsw i32 %x, %y
485  store i32 %sub, i32* %p
486  %shr = lshr i32 %sub, 31
487  ret i32 %shr
488}
489
490define <3 x i42> @lshr_sub_nsw_splat(<3 x i42> %x, <3 x i42> %y) {
491; CHECK-LABEL: @lshr_sub_nsw_splat(
492; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <3 x i42> [[X:%.*]], [[Y:%.*]]
493; CHECK-NEXT:    [[SHR:%.*]] = zext <3 x i1> [[TMP1]] to <3 x i42>
494; CHECK-NEXT:    ret <3 x i42> [[SHR]]
495;
496  %sub = sub nsw <3 x i42> %x, %y
497  %shr = lshr <3 x i42> %sub, <i42 41, i42 41, i42 41>
498  ret <3 x i42> %shr
499}
500
501define <3 x i42> @lshr_sub_nsw_splat_undef(<3 x i42> %x, <3 x i42> %y) {
502; CHECK-LABEL: @lshr_sub_nsw_splat_undef(
503; CHECK-NEXT:    [[SUB:%.*]] = sub nsw <3 x i42> [[X:%.*]], [[Y:%.*]]
504; CHECK-NEXT:    [[SHR:%.*]] = lshr <3 x i42> [[SUB]], <i42 41, i42 undef, i42 41>
505; CHECK-NEXT:    ret <3 x i42> [[SHR]]
506;
507  %sub = sub nsw <3 x i42> %x, %y
508  %shr = lshr <3 x i42> %sub, <i42 41, i42 undef, i42 41>
509  ret <3 x i42> %shr
510}
511
512define i17 @ashr_sub_nsw(i17 %x, i17 %y) {
513; CHECK-LABEL: @ashr_sub_nsw(
514; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i17 [[X:%.*]], [[Y:%.*]]
515; CHECK-NEXT:    [[SHR:%.*]] = sext i1 [[TMP1]] to i17
516; CHECK-NEXT:    ret i17 [[SHR]]
517;
518  %sub = sub nsw i17 %x, %y
519  %shr = ashr i17 %sub, 16
520  ret i17 %shr
521}
522
523; negative test - must shift sign-bit
524
525define i17 @ashr_sub_wrong_amount(i17 %x, i17 %y) {
526; CHECK-LABEL: @ashr_sub_wrong_amount(
527; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i17 [[X:%.*]], [[Y:%.*]]
528; CHECK-NEXT:    [[SHR:%.*]] = ashr i17 [[SUB]], 15
529; CHECK-NEXT:    ret i17 [[SHR]]
530;
531  %sub = sub nsw i17 %x, %y
532  %shr = ashr i17 %sub, 15
533  ret i17 %shr
534}
535
536; negative test - must have nsw
537
538define i32 @ashr_sub(i32 %x, i32 %y) {
539; CHECK-LABEL: @ashr_sub(
540; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
541; CHECK-NEXT:    [[SHR:%.*]] = ashr i32 [[SUB]], 31
542; CHECK-NEXT:    ret i32 [[SHR]]
543;
544  %sub = sub i32 %x, %y
545  %shr = ashr i32 %sub, 31
546  ret i32 %shr
547}
548
549; negative test - one-use
550
551define i32 @ashr_sub_nsw_extra_use(i32 %x, i32 %y, i32* %p) {
552; CHECK-LABEL: @ashr_sub_nsw_extra_use(
553; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]
554; CHECK-NEXT:    store i32 [[SUB]], i32* [[P:%.*]], align 4
555; CHECK-NEXT:    [[SHR:%.*]] = ashr i32 [[SUB]], 31
556; CHECK-NEXT:    ret i32 [[SHR]]
557;
558  %sub = sub nsw i32 %x, %y
559  store i32 %sub, i32* %p
560  %shr = ashr i32 %sub, 31
561  ret i32 %shr
562}
563
564define <3 x i43> @ashr_sub_nsw_splat(<3 x i43> %x, <3 x i43> %y) {
565; CHECK-LABEL: @ashr_sub_nsw_splat(
566; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <3 x i43> [[X:%.*]], [[Y:%.*]]
567; CHECK-NEXT:    [[SHR:%.*]] = sext <3 x i1> [[TMP1]] to <3 x i43>
568; CHECK-NEXT:    ret <3 x i43> [[SHR]]
569;
570  %sub = sub nsw <3 x i43> %x, %y
571  %shr = ashr <3 x i43> %sub, <i43 42, i43 42, i43 42>
572  ret <3 x i43> %shr
573}
574
575define <3 x i43> @ashr_sub_nsw_splat_undef(<3 x i43> %x, <3 x i43> %y) {
576; CHECK-LABEL: @ashr_sub_nsw_splat_undef(
577; CHECK-NEXT:    [[SUB:%.*]] = sub nsw <3 x i43> [[X:%.*]], [[Y:%.*]]
578; CHECK-NEXT:    [[SHR:%.*]] = ashr <3 x i43> [[SUB]], <i43 42, i43 undef, i43 42>
579; CHECK-NEXT:    ret <3 x i43> [[SHR]]
580;
581  %sub = sub nsw <3 x i43> %x, %y
582  %shr = ashr <3 x i43> %sub, <i43 42, i43 undef, i43 42>
583  ret <3 x i43> %shr
584}
585