[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / ashr-lshr.ll
blob72fa0252d83956d525c215935644078eec32d90b
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 define 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]]
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
16 define 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]]
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
28 define 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]]
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
40 define 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]]
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
52 define 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]]
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
64 define <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]]
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
76 define <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]]
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
88 define <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]]
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
100 define <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]]
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
112 define <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]]
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
124 define <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]]
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
136 define <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]]
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
148 define <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]]
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
160 define 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]]
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
172 define 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]]
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
184 define 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]]
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
196 define 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]]
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
208 define <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]]
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
220 define <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]]
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
232 define <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]]
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
244 define <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]]
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
256 ; Negative tests
258 define 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]]
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
273 define 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]]
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
288 define 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]]
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
303 define 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]]
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
318 define 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]]
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
333 define 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]]
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
348 define 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]]
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
363 define 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]]
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
378 define 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]]
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
393 define 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]]
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
408 define <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]]
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
423 define <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]]
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
438 define 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]]
444   %sub = sub nsw i32 %x, %y
445   %shr = lshr i32 %sub, 31
446   ret i32 %shr
449 ; negative test - must shift sign-bit
451 define 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]]
457   %sub = sub nsw i32 %x, %y
458   %shr = lshr i32 %sub, 30
459   ret i32 %shr
462 ; negative test - must have nsw
464 define 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]]
470   %sub = sub i32 %x, %y
471   %shr = lshr i32 %sub, 31
472   ret i32 %shr
475 ; negative test - one-use
477 define 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]]
484   %sub = sub nsw i32 %x, %y
485   store i32 %sub, i32* %p
486   %shr = lshr i32 %sub, 31
487   ret i32 %shr
490 define <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]]
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
501 define <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]]
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
512 define 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]]
518   %sub = sub nsw i17 %x, %y
519   %shr = ashr i17 %sub, 16
520   ret i17 %shr
523 ; negative test - must shift sign-bit
525 define 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]]
531   %sub = sub nsw i17 %x, %y
532   %shr = ashr i17 %sub, 15
533   ret i17 %shr
536 ; negative test - must have nsw
538 define 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]]
544   %sub = sub i32 %x, %y
545   %shr = ashr i32 %sub, 31
546   ret i32 %shr
549 ; negative test - one-use
551 define 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]]
558   %sub = sub nsw i32 %x, %y
559   store i32 %sub, i32* %p
560   %shr = ashr i32 %sub, 31
561   ret i32 %shr
564 define <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]]
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
575 define <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]]
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