1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 ; https://bugs.llvm.org/show_bug.cgi?id=37603
8 ; Should be transformed into:
11 ; ============================================================================ ;
12 ; Basic positive tests
13 ; ============================================================================ ;
15 define i32 @positive_samevar(i32 %x, i32 %y) {
16 ; CHECK-LABEL: @positive_samevar(
17 ; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 -1, [[Y:%.*]]
18 ; CHECK-NEXT: [[RET:%.*]] = and i32 [[TMP1]], [[X:%.*]]
19 ; CHECK-NEXT: ret i32 [[RET]]
22 %ret = lshr i32 %t0, %y
26 define i32 @positive_sameconst(i32 %x) {
27 ; CHECK-LABEL: @positive_sameconst(
28 ; CHECK-NEXT: [[T0:%.*]] = and i32 [[X:%.*]], 134217727
29 ; CHECK-NEXT: ret i32 [[T0]]
32 %ret = lshr i32 %t0, 5
36 define i32 @positive_biggerShl(i32 %x) {
37 ; CHECK-LABEL: @positive_biggerShl(
38 ; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 5
39 ; CHECK-NEXT: [[RET:%.*]] = and i32 [[TMP1]], 134217696
40 ; CHECK-NEXT: ret i32 [[RET]]
43 %ret = lshr i32 %t0, 5
47 define i32 @positive_biggerLshr(i32 %x) {
48 ; CHECK-LABEL: @positive_biggerLshr(
49 ; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 5
50 ; CHECK-NEXT: [[RET:%.*]] = and i32 [[TMP1]], 4194303
51 ; CHECK-NEXT: ret i32 [[RET]]
54 %ret = lshr i32 %t0, 10
58 define i32 @positive_biggerLshr_lshrexact(i32 %x) {
59 ; CHECK-LABEL: @positive_biggerLshr_lshrexact(
60 ; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 [[X:%.*]], 5
61 ; CHECK-NEXT: [[RET:%.*]] = and i32 [[TMP1]], 4194303
62 ; CHECK-NEXT: ret i32 [[RET]]
65 %ret = lshr exact i32 %t0, 10
69 ; ============================================================================ ;
70 ; NUW on the first shift
71 ; ============================================================================ ;
73 define i32 @positive_samevar_shlnuw(i32 %x, i32 %y) {
74 ; CHECK-LABEL: @positive_samevar_shlnuw(
75 ; CHECK-NEXT: ret i32 [[X:%.*]]
77 %t0 = shl nuw i32 %x, %y
78 %ret = lshr i32 %t0, %y ; this one is obviously 'exact'.
82 define i32 @positive_sameconst_shlnuw(i32 %x) {
83 ; CHECK-LABEL: @positive_sameconst_shlnuw(
84 ; CHECK-NEXT: ret i32 [[X:%.*]]
86 %t0 = shl nuw i32 %x, 5
87 %ret = lshr i32 %t0, 5 ; this one is obviously 'exact'.
91 define i32 @positive_biggerShl_shlnuw(i32 %x) {
92 ; CHECK-LABEL: @positive_biggerShl_shlnuw(
93 ; CHECK-NEXT: [[RET:%.*]] = shl nuw nsw i32 [[X:%.*]], 5
94 ; CHECK-NEXT: ret i32 [[RET]]
96 %t0 = shl nuw i32 %x, 10
97 %ret = lshr i32 %t0, 5 ; this one is obviously 'exact'.
101 define i32 @positive_biggerLshr_shlnuw(i32 %x) {
102 ; CHECK-LABEL: @positive_biggerLshr_shlnuw(
103 ; CHECK-NEXT: [[RET:%.*]] = lshr i32 [[X:%.*]], 5
104 ; CHECK-NEXT: ret i32 [[RET]]
106 %t0 = shl nuw i32 %x, 5
107 %ret = lshr i32 %t0, 10
111 define i32 @positive_biggerLshr_shlnuw_lshrexact(i32 %x) {
112 ; CHECK-LABEL: @positive_biggerLshr_shlnuw_lshrexact(
113 ; CHECK-NEXT: [[RET:%.*]] = lshr exact i32 [[X:%.*]], 5
114 ; CHECK-NEXT: ret i32 [[RET]]
116 %t0 = shl nuw i32 %x, 5
117 %ret = lshr exact i32 %t0, 10
121 ; ============================================================================ ;
123 ; ============================================================================ ;
125 define <2 x i32> @positive_samevar_vec(<2 x i32> %x, <2 x i32> %y) {
126 ; CHECK-LABEL: @positive_samevar_vec(
127 ; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> <i32 -1, i32 -1>, [[Y:%.*]]
128 ; CHECK-NEXT: [[RET:%.*]] = and <2 x i32> [[TMP1]], [[X:%.*]]
129 ; CHECK-NEXT: ret <2 x i32> [[RET]]
131 %t0 = shl <2 x i32> %x, %y
132 %ret = lshr <2 x i32> %t0, %y
136 ; ============================================================================ ;
138 ; ============================================================================ ;
140 define <2 x i32> @positive_sameconst_vec(<2 x i32> %x) {
141 ; CHECK-LABEL: @positive_sameconst_vec(
142 ; CHECK-NEXT: [[T0:%.*]] = and <2 x i32> [[X:%.*]], <i32 134217727, i32 134217727>
143 ; CHECK-NEXT: ret <2 x i32> [[T0]]
145 %t0 = shl <2 x i32> %x, <i32 5, i32 5>
146 %ret = lshr <2 x i32> %t0, <i32 5, i32 5>
150 define <3 x i32> @positive_sameconst_vec_undef0(<3 x i32> %x) {
151 ; CHECK-LABEL: @positive_sameconst_vec_undef0(
152 ; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 5, i32 undef, i32 5>
153 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], <i32 5, i32 5, i32 5>
154 ; CHECK-NEXT: ret <3 x i32> [[RET]]
156 %t0 = shl <3 x i32> %x, <i32 5, i32 undef, i32 5>
157 %ret = lshr <3 x i32> %t0, <i32 5, i32 5, i32 5>
161 define <3 x i32> @positive_sameconst_vec_undef1(<3 x i32> %x) {
162 ; CHECK-LABEL: @positive_sameconst_vec_undef1(
163 ; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 5, i32 5, i32 5>
164 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], <i32 5, i32 undef, i32 5>
165 ; CHECK-NEXT: ret <3 x i32> [[RET]]
167 %t0 = shl <3 x i32> %x, <i32 5, i32 5, i32 5>
168 %ret = lshr <3 x i32> %t0, <i32 5, i32 undef, i32 5>
172 define <3 x i32> @positive_sameconst_vec_undef2(<3 x i32> %x) {
173 ; CHECK-LABEL: @positive_sameconst_vec_undef2(
174 ; CHECK-NEXT: [[RET:%.*]] = and <3 x i32> [[X:%.*]], <i32 134217727, i32 poison, i32 134217727>
175 ; CHECK-NEXT: ret <3 x i32> [[RET]]
177 %t0 = shl <3 x i32> %x, <i32 5, i32 undef, i32 5>
178 %ret = lshr <3 x i32> %t0, <i32 5, i32 undef, i32 5>
182 define <2 x i32> @positive_biggerShl_vec(<2 x i32> %x) {
183 ; CHECK-LABEL: @positive_biggerShl_vec(
184 ; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i32> [[X:%.*]], <i32 5, i32 5>
185 ; CHECK-NEXT: [[RET:%.*]] = and <2 x i32> [[TMP1]], <i32 134217696, i32 134217696>
186 ; CHECK-NEXT: ret <2 x i32> [[RET]]
188 %t0 = shl <2 x i32> %x, <i32 10, i32 10>
189 %ret = lshr <2 x i32> %t0, <i32 5, i32 5>
193 define <3 x i32> @positive_biggerShl_vec_undef0(<3 x i32> %x) {
194 ; CHECK-LABEL: @positive_biggerShl_vec_undef0(
195 ; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 10, i32 undef, i32 10>
196 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], <i32 5, i32 5, i32 5>
197 ; CHECK-NEXT: ret <3 x i32> [[RET]]
199 %t0 = shl <3 x i32> %x, <i32 10, i32 undef, i32 10>
200 %ret = lshr <3 x i32> %t0, <i32 5, i32 5, i32 5>
204 define <3 x i32> @positive_biggerShl_vec_undef1(<3 x i32> %x) {
205 ; CHECK-LABEL: @positive_biggerShl_vec_undef1(
206 ; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 10, i32 10, i32 10>
207 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], <i32 5, i32 undef, i32 5>
208 ; CHECK-NEXT: ret <3 x i32> [[RET]]
210 %t0 = shl <3 x i32> %x, <i32 10, i32 10, i32 10>
211 %ret = lshr <3 x i32> %t0, <i32 5, i32 undef, i32 5>
215 define <3 x i32> @positive_biggerShl_vec_undef2(<3 x i32> %x) {
216 ; CHECK-LABEL: @positive_biggerShl_vec_undef2(
217 ; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 10, i32 undef, i32 10>
218 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], <i32 5, i32 undef, i32 5>
219 ; CHECK-NEXT: ret <3 x i32> [[RET]]
221 %t0 = shl <3 x i32> %x, <i32 10, i32 undef, i32 10>
222 %ret = lshr <3 x i32> %t0, <i32 5, i32 undef, i32 5>
226 define <2 x i32> @positive_biggerLshr_vec(<2 x i32> %x) {
227 ; CHECK-LABEL: @positive_biggerLshr_vec(
228 ; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 5, i32 5>
229 ; CHECK-NEXT: [[RET:%.*]] = and <2 x i32> [[TMP1]], <i32 4194303, i32 4194303>
230 ; CHECK-NEXT: ret <2 x i32> [[RET]]
232 %t0 = shl <2 x i32> %x, <i32 5, i32 5>
233 %ret = lshr <2 x i32> %t0, <i32 10, i32 10>
237 define <3 x i32> @positive_biggerLshr_vec_undef0(<3 x i32> %x) {
238 ; CHECK-LABEL: @positive_biggerLshr_vec_undef0(
239 ; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 5, i32 undef, i32 5>
240 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], <i32 10, i32 10, i32 10>
241 ; CHECK-NEXT: ret <3 x i32> [[RET]]
243 %t0 = shl <3 x i32> %x, <i32 5, i32 undef, i32 5>
244 %ret = lshr <3 x i32> %t0, <i32 10, i32 10, i32 10>
248 define <3 x i32> @positive_biggerLshr_vec_undef1(<3 x i32> %x) {
249 ; CHECK-LABEL: @positive_biggerLshr_vec_undef1(
250 ; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 5, i32 5, i32 5>
251 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], <i32 10, i32 undef, i32 10>
252 ; CHECK-NEXT: ret <3 x i32> [[RET]]
254 %t0 = shl <3 x i32> %x, <i32 5, i32 5, i32 5>
255 %ret = lshr <3 x i32> %t0, <i32 10, i32 undef, i32 10>
259 define <3 x i32> @positive_biggerLshr_vec_undef2(<3 x i32> %x) {
260 ; CHECK-LABEL: @positive_biggerLshr_vec_undef2(
261 ; CHECK-NEXT: [[T0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 5, i32 undef, i32 5>
262 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[T0]], <i32 10, i32 undef, i32 10>
263 ; CHECK-NEXT: ret <3 x i32> [[RET]]
265 %t0 = shl <3 x i32> %x, <i32 5, i32 undef, i32 5>
266 %ret = lshr <3 x i32> %t0, <i32 10, i32 undef, i32 10>
270 ; ============================================================================ ;
271 ; Positive multi-use tests with constant
272 ; ============================================================================ ;
274 define i32 @positive_sameconst_multiuse(i32 %x) {
275 ; CHECK-LABEL: @positive_sameconst_multiuse(
276 ; CHECK-NEXT: [[T0:%.*]] = shl i32 [[X:%.*]], 5
277 ; CHECK-NEXT: call void @use32(i32 [[T0]])
278 ; CHECK-NEXT: [[RET:%.*]] = and i32 [[X]], 134217727
279 ; CHECK-NEXT: ret i32 [[RET]]
282 call void @use32(i32 %t0)
283 %ret = lshr i32 %t0, 5
287 define i32 @positive_biggerShl_shlnuw_multiuse(i32 %x) {
288 ; CHECK-LABEL: @positive_biggerShl_shlnuw_multiuse(
289 ; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 [[X:%.*]], 10
290 ; CHECK-NEXT: call void @use32(i32 [[T0]])
291 ; CHECK-NEXT: [[RET:%.*]] = shl nuw nsw i32 [[X]], 5
292 ; CHECK-NEXT: ret i32 [[RET]]
294 %t0 = shl nuw i32 %x, 10
295 call void @use32(i32 %t0)
296 %ret = lshr i32 %t0, 5
300 define i32 @positive_biggerLshr_shlnuw_multiuse(i32 %x) {
301 ; CHECK-LABEL: @positive_biggerLshr_shlnuw_multiuse(
302 ; CHECK-NEXT: [[T0:%.*]] = shl nuw i32 [[X:%.*]], 5
303 ; CHECK-NEXT: call void @use32(i32 [[T0]])
304 ; CHECK-NEXT: [[RET:%.*]] = lshr i32 [[X]], 5
305 ; CHECK-NEXT: ret i32 [[RET]]
307 %t0 = shl nuw i32 %x, 5
308 call void @use32(i32 %t0)
309 %ret = lshr i32 %t0, 10
313 ; negative test - don't create extra instructions
315 define i32 @positive_biggerShl_multiuse_extrainstr(i32 %x) {
316 ; CHECK-LABEL: @positive_biggerShl_multiuse_extrainstr(
317 ; CHECK-NEXT: [[T0:%.*]] = shl i32 [[X:%.*]], 10
318 ; CHECK-NEXT: call void @use32(i32 [[T0]])
319 ; CHECK-NEXT: [[RET:%.*]] = lshr exact i32 [[T0]], 5
320 ; CHECK-NEXT: ret i32 [[RET]]
323 call void @use32(i32 %t0)
324 %ret = lshr i32 %t0, 5
328 ; negative test - don't create extra instructions
330 define i32 @positive_biggerLshr_multiuse_extrainstr(i32 %x) {
331 ; CHECK-LABEL: @positive_biggerLshr_multiuse_extrainstr(
332 ; CHECK-NEXT: [[T0:%.*]] = shl i32 [[X:%.*]], 5
333 ; CHECK-NEXT: call void @use32(i32 [[T0]])
334 ; CHECK-NEXT: [[RET:%.*]] = lshr i32 [[T0]], 10
335 ; CHECK-NEXT: ret i32 [[RET]]
338 call void @use32(i32 %t0)
339 %ret = lshr i32 %t0, 10
343 ; ============================================================================ ;
344 ; Constant Non-Splat Vectors
345 ; ============================================================================ ;
347 define <2 x i32> @positive_biggerShl_vec_nonsplat(<2 x i32> %x) {
348 ; CHECK-LABEL: @positive_biggerShl_vec_nonsplat(
349 ; CHECK-NEXT: [[T0:%.*]] = shl <2 x i32> [[X:%.*]], <i32 5, i32 5>
350 ; CHECK-NEXT: [[RET:%.*]] = lshr <2 x i32> [[T0]], <i32 5, i32 10>
351 ; CHECK-NEXT: ret <2 x i32> [[RET]]
353 %t0 = shl <2 x i32> %x, <i32 5, i32 5>
354 %ret = lshr <2 x i32> %t0, <i32 5, i32 10>
358 define <2 x i32> @positive_biggerLshl_vec_nonsplat(<2 x i32> %x) {
359 ; CHECK-LABEL: @positive_biggerLshl_vec_nonsplat(
360 ; CHECK-NEXT: [[T0:%.*]] = shl <2 x i32> [[X:%.*]], <i32 5, i32 10>
361 ; CHECK-NEXT: [[RET:%.*]] = lshr <2 x i32> [[T0]], <i32 5, i32 5>
362 ; CHECK-NEXT: ret <2 x i32> [[RET]]
364 %t0 = shl <2 x i32> %x, <i32 5, i32 10>
365 %ret = lshr <2 x i32> %t0, <i32 5, i32 5>
369 ; ============================================================================ ;
370 ; Negative tests. Should not be folded.
371 ; ============================================================================ ;
373 define i32 @negative_twovars(i32 %x, i32 %y, i32 %z) {
374 ; CHECK-LABEL: @negative_twovars(
375 ; CHECK-NEXT: [[T0:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]
376 ; CHECK-NEXT: [[RET:%.*]] = lshr i32 [[T0]], [[Z:%.*]]
377 ; CHECK-NEXT: ret i32 [[RET]]
380 %ret = lshr i32 %t0, %z ; $z, not %y
384 declare void @use32(i32)
387 define i32 @negative_oneuse(i32 %x, i32 %y) {
388 ; CHECK-LABEL: @negative_oneuse(
389 ; CHECK-NEXT: [[T0:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]
390 ; CHECK-NEXT: call void @use32(i32 [[T0]])
391 ; CHECK-NEXT: [[RET:%.*]] = lshr exact i32 [[T0]], [[Y]]
392 ; CHECK-NEXT: ret i32 [[RET]]
395 call void @use32(i32 %t0)
396 %ret = lshr i32 %t0, %y