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
11 %r = ashr exact i32 %x, %y
12 %ret = select i1 %cmp, i32 %l, i32 %r
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
24 %ret = select i1 %cmp, i32 %l, i32 %r
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
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
48 %ret = select i1 %cmp, i32 %l, i32 %r
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
59 %r = ashr exact i32 %x, %y
60 %ret = select i1 %cmp, i32 %l, i32 %r
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
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
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
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
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
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
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
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
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
167 %r = ashr exact i32 %x, 8
168 %ret = select i1 %cmp, i32 %r, i32 %l
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
179 %r = ashr exact i32 %x, 8
180 %ret = select i1 %cmp, i32 %l, i32 %r
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
191 %r = ashr exact i32 %x, %y
192 %ret = select i1 %cmp, i32 %r, i32 %l
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
203 %r = ashr exact i32 %x, %y
204 %ret = select i1 %cmp, i32 %r, i32 %l
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
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
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
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
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
268 %r = ashr exact i32 %x, %y
269 %ret = select i1 %cmp, i32 %l, i32 %r
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
283 %r = ashr exact i32 %x, %y
284 %ret = select i1 %cmp, i32 %r, i32 %l
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
299 %ret = select i1 %cmp, i32 %l, i32 %r
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
314 %ret = select i1 %cmp, i32 %l, i32 %r
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
329 %ret = select i1 %cmp, i32 %l, i32 %r
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
344 %ret = select i1 %cmp, i32 %r, i32 %l
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
359 %ret = select i1 %cmp, i32 %l, i32 %r
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
374 %ret = select i1 %cmp, i32 %l, i32 %r
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
389 %ret = select i1 %cmp, i32 %l, i32 %r
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
404 %ret = select i1 %cmp, i32 %l, i32 %r
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
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