comparison test/Transforms/InstCombine/canonicalize-shl-lshr-to-masking.ll @ 147:c2174574ed3a

LLVM 10
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 14 Aug 2019 16:55:33 +0900
parents
children
comparison
equal deleted inserted replaced
134:3a76565eade5 147:c2174574ed3a
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
3
4 ; https://bugs.llvm.org/show_bug.cgi?id=37603
5
6 ; Pattern:
7 ; x << y >> y
8 ; Should be transformed into:
9 ; x & (-1 >> y)
10
11 ; ============================================================================ ;
12 ; Basic positive tests
13 ; ============================================================================ ;
14
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]]
20 ;
21 %tmp0 = shl i32 %x, %y
22 %ret = lshr i32 %tmp0, %y
23 ret i32 %ret
24 }
25
26 define i32 @positive_sameconst(i32 %x) {
27 ; CHECK-LABEL: @positive_sameconst(
28 ; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[X:%.*]], 134217727
29 ; CHECK-NEXT: ret i32 [[TMP0]]
30 ;
31 %tmp0 = shl i32 %x, 5
32 %ret = lshr i32 %tmp0, 5
33 ret i32 %ret
34 }
35
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]]
41 ;
42 %tmp0 = shl i32 %x, 10
43 %ret = lshr i32 %tmp0, 5
44 ret i32 %ret
45 }
46
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]]
52 ;
53 %tmp0 = shl i32 %x, 5
54 %ret = lshr i32 %tmp0, 10
55 ret i32 %ret
56 }
57
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]]
63 ;
64 %tmp0 = shl i32 %x, 5
65 %ret = lshr exact i32 %tmp0, 10
66 ret i32 %ret
67 }
68
69 ; ============================================================================ ;
70 ; NUW on the first shift
71 ; ============================================================================ ;
72
73 define i32 @positive_samevar_shlnuw(i32 %x, i32 %y) {
74 ; CHECK-LABEL: @positive_samevar_shlnuw(
75 ; CHECK-NEXT: ret i32 [[X:%.*]]
76 ;
77 %tmp0 = shl nuw i32 %x, %y
78 %ret = lshr i32 %tmp0, %y ; this one is obviously 'exact'.
79 ret i32 %ret
80 }
81
82 define i32 @positive_sameconst_shlnuw(i32 %x) {
83 ; CHECK-LABEL: @positive_sameconst_shlnuw(
84 ; CHECK-NEXT: ret i32 [[X:%.*]]
85 ;
86 %tmp0 = shl nuw i32 %x, 5
87 %ret = lshr i32 %tmp0, 5 ; this one is obviously 'exact'.
88 ret i32 %ret
89 }
90
91 define i32 @positive_biggerShl_shlnuw(i32 %x) {
92 ; CHECK-LABEL: @positive_biggerShl_shlnuw(
93 ; CHECK-NEXT: [[RET:%.*]] = shl nuw i32 [[X:%.*]], 5
94 ; CHECK-NEXT: ret i32 [[RET]]
95 ;
96 %tmp0 = shl nuw i32 %x, 10
97 %ret = lshr i32 %tmp0, 5 ; this one is obviously 'exact'.
98 ret i32 %ret
99 }
100
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]]
105 ;
106 %tmp0 = shl nuw i32 %x, 5
107 %ret = lshr i32 %tmp0, 10
108 ret i32 %ret
109 }
110
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]]
115 ;
116 %tmp0 = shl nuw i32 %x, 5
117 %ret = lshr exact i32 %tmp0, 10
118 ret i32 %ret
119 }
120
121 ; ============================================================================ ;
122 ; Vector
123 ; ============================================================================ ;
124
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]]
130 ;
131 %tmp0 = shl <2 x i32> %x, %y
132 %ret = lshr <2 x i32> %tmp0, %y
133 ret <2 x i32> %ret
134 }
135
136 ; ============================================================================ ;
137 ; Constant Vectors
138 ; ============================================================================ ;
139
140 define <2 x i32> @positive_sameconst_vec(<2 x i32> %x) {
141 ; CHECK-LABEL: @positive_sameconst_vec(
142 ; CHECK-NEXT: [[TMP0:%.*]] = and <2 x i32> [[X:%.*]], <i32 134217727, i32 134217727>
143 ; CHECK-NEXT: ret <2 x i32> [[TMP0]]
144 ;
145 %tmp0 = shl <2 x i32> %x, <i32 5, i32 5>
146 %ret = lshr <2 x i32> %tmp0, <i32 5, i32 5>
147 ret <2 x i32> %ret
148 }
149
150 define <3 x i32> @positive_sameconst_vec_undef0(<3 x i32> %x) {
151 ; CHECK-LABEL: @positive_sameconst_vec_undef0(
152 ; CHECK-NEXT: [[TMP0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 5, i32 undef, i32 5>
153 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[TMP0]], <i32 5, i32 5, i32 5>
154 ; CHECK-NEXT: ret <3 x i32> [[RET]]
155 ;
156 %tmp0 = shl <3 x i32> %x, <i32 5, i32 undef, i32 5>
157 %ret = lshr <3 x i32> %tmp0, <i32 5, i32 5, i32 5>
158 ret <3 x i32> %ret
159 }
160
161 define <3 x i32> @positive_sameconst_vec_undef1(<3 x i32> %x) {
162 ; CHECK-LABEL: @positive_sameconst_vec_undef1(
163 ; CHECK-NEXT: [[TMP0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 5, i32 5, i32 5>
164 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[TMP0]], <i32 5, i32 undef, i32 5>
165 ; CHECK-NEXT: ret <3 x i32> [[RET]]
166 ;
167 %tmp0 = shl <3 x i32> %x, <i32 5, i32 5, i32 5>
168 %ret = lshr <3 x i32> %tmp0, <i32 5, i32 undef, i32 5>
169 ret <3 x i32> %ret
170 }
171
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 undef, i32 134217727>
175 ; CHECK-NEXT: ret <3 x i32> [[RET]]
176 ;
177 %tmp0 = shl <3 x i32> %x, <i32 5, i32 undef, i32 5>
178 %ret = lshr <3 x i32> %tmp0, <i32 5, i32 undef, i32 5>
179 ret <3 x i32> %ret
180 }
181
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]]
187 ;
188 %tmp0 = shl <2 x i32> %x, <i32 10, i32 10>
189 %ret = lshr <2 x i32> %tmp0, <i32 5, i32 5>
190 ret <2 x i32> %ret
191 }
192
193 define <3 x i32> @positive_biggerShl_vec_undef0(<3 x i32> %x) {
194 ; CHECK-LABEL: @positive_biggerShl_vec_undef0(
195 ; CHECK-NEXT: [[TMP0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 10, i32 undef, i32 10>
196 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[TMP0]], <i32 5, i32 5, i32 5>
197 ; CHECK-NEXT: ret <3 x i32> [[RET]]
198 ;
199 %tmp0 = shl <3 x i32> %x, <i32 10, i32 undef, i32 10>
200 %ret = lshr <3 x i32> %tmp0, <i32 5, i32 5, i32 5>
201 ret <3 x i32> %ret
202 }
203
204 define <3 x i32> @positive_biggerShl_vec_undef1(<3 x i32> %x) {
205 ; CHECK-LABEL: @positive_biggerShl_vec_undef1(
206 ; CHECK-NEXT: [[TMP0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 10, i32 10, i32 10>
207 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[TMP0]], <i32 5, i32 undef, i32 5>
208 ; CHECK-NEXT: ret <3 x i32> [[RET]]
209 ;
210 %tmp0 = shl <3 x i32> %x, <i32 10, i32 10, i32 10>
211 %ret = lshr <3 x i32> %tmp0, <i32 5, i32 undef, i32 5>
212 ret <3 x i32> %ret
213 }
214
215 define <3 x i32> @positive_biggerShl_vec_undef2(<3 x i32> %x) {
216 ; CHECK-LABEL: @positive_biggerShl_vec_undef2(
217 ; CHECK-NEXT: [[TMP0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 10, i32 undef, i32 10>
218 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[TMP0]], <i32 5, i32 undef, i32 5>
219 ; CHECK-NEXT: ret <3 x i32> [[RET]]
220 ;
221 %tmp0 = shl <3 x i32> %x, <i32 10, i32 undef, i32 10>
222 %ret = lshr <3 x i32> %tmp0, <i32 5, i32 undef, i32 5>
223 ret <3 x i32> %ret
224 }
225
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]]
231 ;
232 %tmp0 = shl <2 x i32> %x, <i32 5, i32 5>
233 %ret = lshr <2 x i32> %tmp0, <i32 10, i32 10>
234 ret <2 x i32> %ret
235 }
236
237 define <3 x i32> @positive_biggerLshr_vec_undef0(<3 x i32> %x) {
238 ; CHECK-LABEL: @positive_biggerLshr_vec_undef0(
239 ; CHECK-NEXT: [[TMP0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 5, i32 undef, i32 5>
240 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[TMP0]], <i32 10, i32 10, i32 10>
241 ; CHECK-NEXT: ret <3 x i32> [[RET]]
242 ;
243 %tmp0 = shl <3 x i32> %x, <i32 5, i32 undef, i32 5>
244 %ret = lshr <3 x i32> %tmp0, <i32 10, i32 10, i32 10>
245 ret <3 x i32> %ret
246 }
247
248 define <3 x i32> @positive_biggerLshr_vec_undef1(<3 x i32> %x) {
249 ; CHECK-LABEL: @positive_biggerLshr_vec_undef1(
250 ; CHECK-NEXT: [[TMP0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 5, i32 5, i32 5>
251 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[TMP0]], <i32 10, i32 undef, i32 10>
252 ; CHECK-NEXT: ret <3 x i32> [[RET]]
253 ;
254 %tmp0 = shl <3 x i32> %x, <i32 5, i32 5, i32 5>
255 %ret = lshr <3 x i32> %tmp0, <i32 10, i32 undef, i32 10>
256 ret <3 x i32> %ret
257 }
258
259 define <3 x i32> @positive_biggerLshr_vec_undef2(<3 x i32> %x) {
260 ; CHECK-LABEL: @positive_biggerLshr_vec_undef2(
261 ; CHECK-NEXT: [[TMP0:%.*]] = shl <3 x i32> [[X:%.*]], <i32 5, i32 undef, i32 5>
262 ; CHECK-NEXT: [[RET:%.*]] = lshr <3 x i32> [[TMP0]], <i32 10, i32 undef, i32 10>
263 ; CHECK-NEXT: ret <3 x i32> [[RET]]
264 ;
265 %tmp0 = shl <3 x i32> %x, <i32 5, i32 undef, i32 5>
266 %ret = lshr <3 x i32> %tmp0, <i32 10, i32 undef, i32 10>
267 ret <3 x i32> %ret
268 }
269
270 ; ============================================================================ ;
271 ; Positive multi-use tests with constant
272 ; ============================================================================ ;
273
274 define i32 @positive_sameconst_multiuse(i32 %x) {
275 ; CHECK-LABEL: @positive_sameconst_multiuse(
276 ; CHECK-NEXT: [[TMP0:%.*]] = shl i32 [[X:%.*]], 5
277 ; CHECK-NEXT: call void @use32(i32 [[TMP0]])
278 ; CHECK-NEXT: [[RET:%.*]] = and i32 [[X]], 134217727
279 ; CHECK-NEXT: ret i32 [[RET]]
280 ;
281 %tmp0 = shl i32 %x, 5
282 call void @use32(i32 %tmp0)
283 %ret = lshr i32 %tmp0, 5
284 ret i32 %ret
285 }
286
287 define i32 @positive_biggerShl_shlnuw_multiuse(i32 %x) {
288 ; CHECK-LABEL: @positive_biggerShl_shlnuw_multiuse(
289 ; CHECK-NEXT: [[TMP0:%.*]] = shl nuw i32 [[X:%.*]], 10
290 ; CHECK-NEXT: call void @use32(i32 [[TMP0]])
291 ; CHECK-NEXT: [[RET:%.*]] = shl nuw i32 [[X]], 5
292 ; CHECK-NEXT: ret i32 [[RET]]
293 ;
294 %tmp0 = shl nuw i32 %x, 10
295 call void @use32(i32 %tmp0)
296 %ret = lshr i32 %tmp0, 5
297 ret i32 %ret
298 }
299
300 define i32 @positive_biggerLshr_shlnuw_multiuse(i32 %x) {
301 ; CHECK-LABEL: @positive_biggerLshr_shlnuw_multiuse(
302 ; CHECK-NEXT: [[TMP0:%.*]] = shl nuw i32 [[X:%.*]], 5
303 ; CHECK-NEXT: call void @use32(i32 [[TMP0]])
304 ; CHECK-NEXT: [[RET:%.*]] = lshr i32 [[X]], 5
305 ; CHECK-NEXT: ret i32 [[RET]]
306 ;
307 %tmp0 = shl nuw i32 %x, 5
308 call void @use32(i32 %tmp0)
309 %ret = lshr i32 %tmp0, 10
310 ret i32 %ret
311 }
312
313 ; NOTE: creates one extra instruction, but this seems intentional.
314 define i32 @positive_biggerShl_multiuse_extrainstr(i32 %x) {
315 ; CHECK-LABEL: @positive_biggerShl_multiuse_extrainstr(
316 ; CHECK-NEXT: [[TMP0:%.*]] = shl i32 [[X:%.*]], 10
317 ; CHECK-NEXT: call void @use32(i32 [[TMP0]])
318 ; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X]], 5
319 ; CHECK-NEXT: [[RET:%.*]] = and i32 [[TMP1]], 134217696
320 ; CHECK-NEXT: ret i32 [[RET]]
321 ;
322 %tmp0 = shl i32 %x, 10
323 call void @use32(i32 %tmp0)
324 %ret = lshr i32 %tmp0, 5
325 ret i32 %ret
326 }
327
328 ; NOTE: creates one extra instruction, but this seems intentional.
329 define i32 @positive_biggerLshr_multiuse_extrainstr(i32 %x) {
330 ; CHECK-LABEL: @positive_biggerLshr_multiuse_extrainstr(
331 ; CHECK-NEXT: [[TMP0:%.*]] = shl i32 [[X:%.*]], 5
332 ; CHECK-NEXT: call void @use32(i32 [[TMP0]])
333 ; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X]], 5
334 ; CHECK-NEXT: [[RET:%.*]] = and i32 [[TMP1]], 4194303
335 ; CHECK-NEXT: ret i32 [[RET]]
336 ;
337 %tmp0 = shl i32 %x, 5
338 call void @use32(i32 %tmp0)
339 %ret = lshr i32 %tmp0, 10
340 ret i32 %ret
341 }
342
343 ; ============================================================================ ;
344 ; Constant Non-Splat Vectors
345 ; ============================================================================ ;
346
347 define <2 x i32> @positive_biggerShl_vec_nonsplat(<2 x i32> %x) {
348 ; CHECK-LABEL: @positive_biggerShl_vec_nonsplat(
349 ; CHECK-NEXT: [[TMP0:%.*]] = shl <2 x i32> [[X:%.*]], <i32 5, i32 5>
350 ; CHECK-NEXT: [[RET:%.*]] = lshr <2 x i32> [[TMP0]], <i32 5, i32 10>
351 ; CHECK-NEXT: ret <2 x i32> [[RET]]
352 ;
353 %tmp0 = shl <2 x i32> %x, <i32 5, i32 5>
354 %ret = lshr <2 x i32> %tmp0, <i32 5, i32 10>
355 ret <2 x i32> %ret
356 }
357
358 define <2 x i32> @positive_biggerLshl_vec_nonsplat(<2 x i32> %x) {
359 ; CHECK-LABEL: @positive_biggerLshl_vec_nonsplat(
360 ; CHECK-NEXT: [[TMP0:%.*]] = shl <2 x i32> [[X:%.*]], <i32 5, i32 10>
361 ; CHECK-NEXT: [[RET:%.*]] = lshr <2 x i32> [[TMP0]], <i32 5, i32 5>
362 ; CHECK-NEXT: ret <2 x i32> [[RET]]
363 ;
364 %tmp0 = shl <2 x i32> %x, <i32 5, i32 10>
365 %ret = lshr <2 x i32> %tmp0, <i32 5, i32 5>
366 ret <2 x i32> %ret
367 }
368
369 ; ============================================================================ ;
370 ; Negative tests. Should not be folded.
371 ; ============================================================================ ;
372
373 define i32 @negative_twovars(i32 %x, i32 %y, i32 %z) {
374 ; CHECK-LABEL: @negative_twovars(
375 ; CHECK-NEXT: [[TMP0:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]
376 ; CHECK-NEXT: [[RET:%.*]] = lshr i32 [[TMP0]], [[Z:%.*]]
377 ; CHECK-NEXT: ret i32 [[RET]]
378 ;
379 %tmp0 = shl i32 %x, %y
380 %ret = lshr i32 %tmp0, %z ; $z, not %y
381 ret i32 %ret
382 }
383
384 declare void @use32(i32)
385
386 ; One use only.
387 define i32 @negative_oneuse(i32 %x, i32 %y) {
388 ; CHECK-LABEL: @negative_oneuse(
389 ; CHECK-NEXT: [[TMP0:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]
390 ; CHECK-NEXT: call void @use32(i32 [[TMP0]])
391 ; CHECK-NEXT: [[RET:%.*]] = lshr i32 [[TMP0]], [[Y]]
392 ; CHECK-NEXT: ret i32 [[RET]]
393 ;
394 %tmp0 = shl i32 %x, %y
395 call void @use32(i32 %tmp0)
396 %ret = lshr i32 %tmp0, %y
397 ret i32 %ret
398 }