1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc --verify-machineinstrs -mtriple=thumbv8.1m.main-none-eabi -mattr=+mve %s -o - | FileCheck %s -check-prefix=CHECK --check-prefix=CHECK-MVE
3 ; RUN: llc --verify-machineinstrs -mtriple=thumbv8.1m.main-none-eabi %s -o - | FileCheck %s -check-prefix=CHECK --check-prefix=CHECK-NON-MVE
5 define i64 @shift_left_reg(i64 %x, i64 %y) {
6 ; CHECK-MVE-LABEL: shift_left_reg:
7 ; CHECK-MVE: @ %bb.0: @ %entry
8 ; CHECK-MVE-NEXT: lsll r0, r1, r2
9 ; CHECK-MVE-NEXT: bx lr
11 ; CHECK-NON-MVE-LABEL: shift_left_reg:
12 ; CHECK-NON-MVE: @ %bb.0: @ %entry
13 ; CHECK-NON-MVE-NEXT: rsb.w r3, r2, #32
14 ; CHECK-NON-MVE-NEXT: lsls r1, r2
15 ; CHECK-NON-MVE-NEXT: lsr.w r3, r0, r3
16 ; CHECK-NON-MVE-NEXT: orrs r1, r3
17 ; CHECK-NON-MVE-NEXT: subs.w r3, r2, #32
18 ; CHECK-NON-MVE-NEXT: it pl
19 ; CHECK-NON-MVE-NEXT: lslpl.w r1, r0, r3
20 ; CHECK-NON-MVE-NEXT: lsl.w r0, r0, r2
21 ; CHECK-NON-MVE-NEXT: it pl
22 ; CHECK-NON-MVE-NEXT: movpl r0, #0
23 ; CHECK-NON-MVE-NEXT: bx lr
29 define i64 @shift_left_imm(i64 %x) {
30 ; CHECK-MVE-LABEL: shift_left_imm:
31 ; CHECK-MVE: @ %bb.0: @ %entry
32 ; CHECK-MVE-NEXT: lsll r0, r1, #3
33 ; CHECK-MVE-NEXT: bx lr
35 ; CHECK-NON-MVE-LABEL: shift_left_imm:
36 ; CHECK-NON-MVE: @ %bb.0: @ %entry
37 ; CHECK-NON-MVE-NEXT: lsls r1, r1, #3
38 ; CHECK-NON-MVE-NEXT: orr.w r1, r1, r0, lsr #29
39 ; CHECK-NON-MVE-NEXT: lsls r0, r0, #3
40 ; CHECK-NON-MVE-NEXT: bx lr
46 define i64 @shift_left_imm_big(i64 %x) {
47 ; CHECK-LABEL: shift_left_imm_big:
48 ; CHECK: @ %bb.0: @ %entry
49 ; CHECK-NEXT: lsls r1, r0, #16
50 ; CHECK-NEXT: movs r0, #0
57 define i64 @shift_left_imm_big2(i64 %x) {
58 ; CHECK-LABEL: shift_left_imm_big2:
59 ; CHECK: @ %bb.0: @ %entry
60 ; CHECK-NEXT: mov r1, r0
61 ; CHECK-NEXT: movs r0, #0
68 define i64 @shift_left_imm_big3(i64 %x) {
69 ; CHECK-LABEL: shift_left_imm_big3:
70 ; CHECK: @ %bb.0: @ %entry
71 ; CHECK-NEXT: lsls r1, r0, #1
72 ; CHECK-NEXT: movs r0, #0
79 define i64 @shift_right_reg(i64 %x, i64 %y) {
80 ; CHECK-MVE-LABEL: shift_right_reg:
81 ; CHECK-MVE: @ %bb.0: @ %entry
82 ; CHECK-MVE-NEXT: rsbs r2, r2, #0
83 ; CHECK-MVE-NEXT: lsll r0, r1, r2
84 ; CHECK-MVE-NEXT: bx lr
86 ; CHECK-NON-MVE-LABEL: shift_right_reg:
87 ; CHECK-NON-MVE: @ %bb.0: @ %entry
88 ; CHECK-NON-MVE-NEXT: rsb.w r3, r2, #32
89 ; CHECK-NON-MVE-NEXT: lsrs r0, r2
90 ; CHECK-NON-MVE-NEXT: lsl.w r3, r1, r3
91 ; CHECK-NON-MVE-NEXT: orrs r0, r3
92 ; CHECK-NON-MVE-NEXT: subs.w r3, r2, #32
93 ; CHECK-NON-MVE-NEXT: it pl
94 ; CHECK-NON-MVE-NEXT: lsrpl.w r0, r1, r3
95 ; CHECK-NON-MVE-NEXT: lsr.w r1, r1, r2
96 ; CHECK-NON-MVE-NEXT: it pl
97 ; CHECK-NON-MVE-NEXT: movpl r1, #0
98 ; CHECK-NON-MVE-NEXT: bx lr
100 %shr = lshr i64 %x, %y
104 define i64 @shift_right_imm(i64 %x) {
105 ; CHECK-MVE-LABEL: shift_right_imm:
106 ; CHECK-MVE: @ %bb.0: @ %entry
107 ; CHECK-MVE-NEXT: lsrl r0, r1, #3
108 ; CHECK-MVE-NEXT: bx lr
110 ; CHECK-NON-MVE-LABEL: shift_right_imm:
111 ; CHECK-NON-MVE: @ %bb.0: @ %entry
112 ; CHECK-NON-MVE-NEXT: lsrs r0, r0, #3
113 ; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #29
114 ; CHECK-NON-MVE-NEXT: lsrs r1, r1, #3
115 ; CHECK-NON-MVE-NEXT: bx lr
117 %shr = lshr i64 %x, 3
121 define i64 @shift_right_imm_big(i64 %x) {
122 ; CHECK-LABEL: shift_right_imm_big:
123 ; CHECK: @ %bb.0: @ %entry
124 ; CHECK-NEXT: lsrs r0, r1, #16
125 ; CHECK-NEXT: movs r1, #0
128 %shr = lshr i64 %x, 48
132 define i64 @shift_right_imm_big2(i64 %x) {
133 ; CHECK-LABEL: shift_right_imm_big2:
134 ; CHECK: @ %bb.0: @ %entry
135 ; CHECK-NEXT: mov r0, r1
136 ; CHECK-NEXT: movs r1, #0
139 %shr = lshr i64 %x, 32
143 define i64 @shift_right_imm_big3(i64 %x) {
144 ; CHECK-LABEL: shift_right_imm_big3:
145 ; CHECK: @ %bb.0: @ %entry
146 ; CHECK-NEXT: lsrs r0, r1, #1
147 ; CHECK-NEXT: movs r1, #0
150 %shr = lshr i64 %x, 33
154 define i64 @shift_arithmetic_right_reg(i64 %x, i64 %y) {
155 ; CHECK-MVE-LABEL: shift_arithmetic_right_reg:
156 ; CHECK-MVE: @ %bb.0: @ %entry
157 ; CHECK-MVE-NEXT: asrl r0, r1, r2
158 ; CHECK-MVE-NEXT: bx lr
160 ; CHECK-NON-MVE-LABEL: shift_arithmetic_right_reg:
161 ; CHECK-NON-MVE: @ %bb.0: @ %entry
162 ; CHECK-NON-MVE-NEXT: rsb.w r3, r2, #32
163 ; CHECK-NON-MVE-NEXT: lsrs r0, r2
164 ; CHECK-NON-MVE-NEXT: lsl.w r3, r1, r3
165 ; CHECK-NON-MVE-NEXT: orrs r0, r3
166 ; CHECK-NON-MVE-NEXT: subs.w r3, r2, #32
167 ; CHECK-NON-MVE-NEXT: asr.w r2, r1, r2
168 ; CHECK-NON-MVE-NEXT: it pl
169 ; CHECK-NON-MVE-NEXT: asrpl.w r0, r1, r3
170 ; CHECK-NON-MVE-NEXT: it pl
171 ; CHECK-NON-MVE-NEXT: asrpl r2, r1, #31
172 ; CHECK-NON-MVE-NEXT: mov r1, r2
173 ; CHECK-NON-MVE-NEXT: bx lr
175 %shr = ashr i64 %x, %y
179 define i64 @shift_arithmetic_right_imm(i64 %x) {
180 ; CHECK-MVE-LABEL: shift_arithmetic_right_imm:
181 ; CHECK-MVE: @ %bb.0: @ %entry
182 ; CHECK-MVE-NEXT: asrl r0, r1, #3
183 ; CHECK-MVE-NEXT: bx lr
185 ; CHECK-NON-MVE-LABEL: shift_arithmetic_right_imm:
186 ; CHECK-NON-MVE: @ %bb.0: @ %entry
187 ; CHECK-NON-MVE-NEXT: lsrs r0, r0, #3
188 ; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #29
189 ; CHECK-NON-MVE-NEXT: asrs r1, r1, #3
190 ; CHECK-NON-MVE-NEXT: bx lr
192 %shr = ashr i64 %x, 3
196 %struct.bar = type { i16, i8, [5 x i8] }
198 define arm_aapcs_vfpcc void @fn1(%struct.bar* nocapture %a) {
199 ; CHECK-MVE-LABEL: fn1:
200 ; CHECK-MVE: @ %bb.0: @ %entry
201 ; CHECK-MVE-NEXT: ldr r2, [r0, #4]
202 ; CHECK-MVE-NEXT: movs r1, #0
203 ; CHECK-MVE-NEXT: lsll r2, r1, #8
204 ; CHECK-MVE-NEXT: strb r1, [r0, #7]
205 ; CHECK-MVE-NEXT: str.w r2, [r0, #3]
206 ; CHECK-MVE-NEXT: bx lr
208 ; CHECK-NON-MVE-LABEL: fn1:
209 ; CHECK-NON-MVE: @ %bb.0: @ %entry
210 ; CHECK-NON-MVE-NEXT: ldr r1, [r0, #4]
211 ; CHECK-NON-MVE-NEXT: lsrs r2, r1, #24
212 ; CHECK-NON-MVE-NEXT: lsls r1, r1, #8
213 ; CHECK-NON-MVE-NEXT: strb r2, [r0, #7]
214 ; CHECK-NON-MVE-NEXT: str.w r1, [r0, #3]
215 ; CHECK-NON-MVE-NEXT: bx lr
217 %carey = getelementptr inbounds %struct.bar, %struct.bar* %a, i32 0, i32 2
218 %0 = bitcast [5 x i8]* %carey to i40*
219 %bf.load = load i40, i40* %0, align 1
220 %bf.clear = and i40 %bf.load, -256
221 store i40 %bf.clear, i40* %0, align 1
225 %struct.a = type { i96 }
227 define void @lsll_128bit_shift(%struct.a* nocapture %x) local_unnamed_addr #0 {
228 ; CHECK-LABEL: lsll_128bit_shift:
229 ; CHECK: @ %bb.0: @ %entry
230 ; CHECK-NEXT: movs r1, #0
231 ; CHECK-NEXT: strd r1, r1, [r0]
232 ; CHECK-NEXT: str r1, [r0, #8]
235 %0 = bitcast %struct.a* %x to i128*
236 %bf.load = load i128, i128* %0, align 8
237 %bf.clear4 = and i128 %bf.load, -79228162514264337593543950336
238 store i128 %bf.clear4, i128* %0, align 8
242 %struct.b = type { i184 }
244 define void @lsll_256bit_shift(%struct.b* nocapture %x) local_unnamed_addr #0 {
245 ; CHECK-LABEL: lsll_256bit_shift:
246 ; CHECK: @ %bb.0: @ %entry
247 ; CHECK-NEXT: movs r1, #0
248 ; CHECK-NEXT: str r1, [r0, #16]
249 ; CHECK-NEXT: strd r1, r1, [r0, #8]
250 ; CHECK-NEXT: strd r1, r1, [r0]
251 ; CHECK-NEXT: ldrb r1, [r0, #23]
252 ; CHECK-NEXT: lsls r1, r1, #24
253 ; CHECK-NEXT: str r1, [r0, #20]
256 %0 = bitcast %struct.b* %x to i192*
257 %bf.load = load i192, i192* %0, align 8
258 %bf.clear4 = and i192 %bf.load, -24519928653854221733733552434404946937899825954937634816
259 store i192 %bf.clear4, i192* %0, align 8
264 define i32 @ashr_demand_bottom3(i64 %x) {
265 ; CHECK-MVE-LABEL: ashr_demand_bottom3:
266 ; CHECK-MVE: @ %bb.0: @ %entry
267 ; CHECK-MVE-NEXT: lsrl r0, r1, #3
268 ; CHECK-MVE-NEXT: bx lr
270 ; CHECK-NON-MVE-LABEL: ashr_demand_bottom3:
271 ; CHECK-NON-MVE: @ %bb.0: @ %entry
272 ; CHECK-NON-MVE-NEXT: lsrs r0, r0, #3
273 ; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #29
274 ; CHECK-NON-MVE-NEXT: bx lr
276 %shr = ashr i64 %x, 3
277 %t = trunc i64 %shr to i32
281 define i32 @lshr_demand_bottom3(i64 %x) {
282 ; CHECK-MVE-LABEL: lshr_demand_bottom3:
283 ; CHECK-MVE: @ %bb.0: @ %entry
284 ; CHECK-MVE-NEXT: lsrl r0, r1, #3
285 ; CHECK-MVE-NEXT: bx lr
287 ; CHECK-NON-MVE-LABEL: lshr_demand_bottom3:
288 ; CHECK-NON-MVE: @ %bb.0: @ %entry
289 ; CHECK-NON-MVE-NEXT: lsrs r0, r0, #3
290 ; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #29
291 ; CHECK-NON-MVE-NEXT: bx lr
293 %shr = lshr i64 %x, 3
294 %t = trunc i64 %shr to i32
298 define i32 @lsl_demand_bottom3(i64 %x) {
299 ; CHECK-LABEL: lsl_demand_bottom3:
300 ; CHECK: @ %bb.0: @ %entry
301 ; CHECK-NEXT: lsls r0, r0, #3
305 %t = trunc i64 %shr to i32
310 define i32 @ashr_demand_bottom31(i64 %x) {
311 ; CHECK-MVE-LABEL: ashr_demand_bottom31:
312 ; CHECK-MVE: @ %bb.0: @ %entry
313 ; CHECK-MVE-NEXT: lsrl r0, r1, #31
314 ; CHECK-MVE-NEXT: bx lr
316 ; CHECK-NON-MVE-LABEL: ashr_demand_bottom31:
317 ; CHECK-NON-MVE: @ %bb.0: @ %entry
318 ; CHECK-NON-MVE-NEXT: lsrs r0, r0, #31
319 ; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #1
320 ; CHECK-NON-MVE-NEXT: bx lr
322 %shr = ashr i64 %x, 31
323 %t = trunc i64 %shr to i32
327 define i32 @lshr_demand_bottom31(i64 %x) {
328 ; CHECK-MVE-LABEL: lshr_demand_bottom31:
329 ; CHECK-MVE: @ %bb.0: @ %entry
330 ; CHECK-MVE-NEXT: lsrl r0, r1, #31
331 ; CHECK-MVE-NEXT: bx lr
333 ; CHECK-NON-MVE-LABEL: lshr_demand_bottom31:
334 ; CHECK-NON-MVE: @ %bb.0: @ %entry
335 ; CHECK-NON-MVE-NEXT: lsrs r0, r0, #31
336 ; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #1
337 ; CHECK-NON-MVE-NEXT: bx lr
339 %shr = lshr i64 %x, 31
340 %t = trunc i64 %shr to i32
344 define i32 @lsl_demand_bottom31(i64 %x) {
345 ; CHECK-LABEL: lsl_demand_bottom31:
346 ; CHECK: @ %bb.0: @ %entry
347 ; CHECK-NEXT: lsls r0, r0, #31
350 %shr = shl i64 %x, 31
351 %t = trunc i64 %shr to i32
356 define i32 @ashr_demand_bottom32(i64 %x) {
357 ; CHECK-LABEL: ashr_demand_bottom32:
358 ; CHECK: @ %bb.0: @ %entry
359 ; CHECK-NEXT: mov r0, r1
362 %shr = ashr i64 %x, 32
363 %t = trunc i64 %shr to i32
367 define i32 @lshr_demand_bottom32(i64 %x) {
368 ; CHECK-LABEL: lshr_demand_bottom32:
369 ; CHECK: @ %bb.0: @ %entry
370 ; CHECK-NEXT: mov r0, r1
373 %shr = lshr i64 %x, 32
374 %t = trunc i64 %shr to i32
378 define i32 @lsl_demand_bottom32(i64 %x) {
379 ; CHECK-LABEL: lsl_demand_bottom32:
380 ; CHECK: @ %bb.0: @ %entry
381 ; CHECK-NEXT: movs r0, #0
384 %shr = shl i64 %x, 32
385 %t = trunc i64 %shr to i32
390 define i32 @ashr_demand_bottom44(i64 %x) {
391 ; CHECK-LABEL: ashr_demand_bottom44:
392 ; CHECK: @ %bb.0: @ %entry
393 ; CHECK-NEXT: asrs r0, r1, #12
396 %shr = ashr i64 %x, 44
397 %t = trunc i64 %shr to i32
401 define i32 @lshr_demand_bottom44(i64 %x) {
402 ; CHECK-LABEL: lshr_demand_bottom44:
403 ; CHECK: @ %bb.0: @ %entry
404 ; CHECK-NEXT: lsrs r0, r1, #12
407 %shr = lshr i64 %x, 44
408 %t = trunc i64 %shr to i32
412 define i32 @lsl_demand_bottom44(i64 %x) {
413 ; CHECK-LABEL: lsl_demand_bottom44:
414 ; CHECK: @ %bb.0: @ %entry
415 ; CHECK-NEXT: movs r0, #0
418 %shr = shl i64 %x, 44
419 %t = trunc i64 %shr to i32
424 define i32 @ashr_demand_bottommask(i64 %x) {
425 ; CHECK-LABEL: ashr_demand_bottommask:
426 ; CHECK: @ %bb.0: @ %entry
427 ; CHECK-NEXT: lsls r0, r1, #1
430 %shr = ashr i64 %x, 31
431 %t = trunc i64 %shr to i32
436 define i32 @lshr_demand_bottommask(i64 %x) {
437 ; CHECK-LABEL: lshr_demand_bottommask:
438 ; CHECK: @ %bb.0: @ %entry
439 ; CHECK-NEXT: lsls r0, r1, #1
442 %shr = lshr i64 %x, 31
443 %t = trunc i64 %shr to i32
448 define i32 @lsl_demand_bottommask(i64 %x) {
449 ; CHECK-LABEL: lsl_demand_bottommask:
450 ; CHECK: @ %bb.0: @ %entry
451 ; CHECK-NEXT: lsls r0, r0, #31
454 %shr = shl i64 %x, 31
455 %t = trunc i64 %shr to i32
460 define i32 @ashr_demand_bottommask2(i64 %x) {
461 ; CHECK-LABEL: ashr_demand_bottommask2:
462 ; CHECK: @ %bb.0: @ %entry
463 ; CHECK-NEXT: mvn r0, #2
464 ; CHECK-NEXT: and.w r0, r0, r1, lsl #1
467 %shr = ashr i64 %x, 31
468 %t = trunc i64 %shr to i32
473 define i32 @lshr_demand_bottommask2(i64 %x) {
474 ; CHECK-LABEL: lshr_demand_bottommask2:
475 ; CHECK: @ %bb.0: @ %entry
476 ; CHECK-NEXT: mvn r0, #2
477 ; CHECK-NEXT: and.w r0, r0, r1, lsl #1
480 %shr = lshr i64 %x, 31
481 %t = trunc i64 %shr to i32
486 define i32 @lsl_demand_bottommask2(i64 %x) {
487 ; CHECK-LABEL: lsl_demand_bottommask2:
488 ; CHECK: @ %bb.0: @ %entry
489 ; CHECK-NEXT: lsls r0, r0, #31
492 %shr = shl i64 %x, 31
493 %t = trunc i64 %shr to i32
498 define i32 @lsl_demand_topmask(i64 %x) {
499 ; CHECK-LABEL: lsl_demand_topmask:
500 ; CHECK: @ %bb.0: @ %entry
501 ; CHECK-NEXT: ubfx r0, r0, #1, #28
505 %a = and i64 %sh, 1152921500311879680 ;0x0fffffff00000000
507 %t = trunc i64 %l to i32