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(ptr 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, ptr %a, i32 0, i32 2
218 %bf.load = load i40, ptr %carey, align 1
219 %bf.clear = and i40 %bf.load, -256
220 store i40 %bf.clear, ptr %carey, align 1
224 %struct.a = type { i96 }
226 define void @lsll_128bit_shift(ptr nocapture %x) local_unnamed_addr #0 {
227 ; CHECK-LABEL: lsll_128bit_shift:
228 ; CHECK: @ %bb.0: @ %entry
229 ; CHECK-NEXT: movs r1, #0
230 ; CHECK-NEXT: strd r1, r1, [r0]
231 ; CHECK-NEXT: str r1, [r0, #8]
234 %bf.load = load i128, ptr %x, align 8
235 %bf.clear4 = and i128 %bf.load, -79228162514264337593543950336
236 store i128 %bf.clear4, ptr %x, align 8
240 %struct.b = type { i184 }
242 define void @lsll_256bit_shift(ptr nocapture %x) local_unnamed_addr #0 {
243 ; CHECK-LABEL: lsll_256bit_shift:
244 ; CHECK: @ %bb.0: @ %entry
245 ; CHECK-NEXT: movs r1, #0
246 ; CHECK-NEXT: str r1, [r0, #16]
247 ; CHECK-NEXT: strd r1, r1, [r0, #8]
248 ; CHECK-NEXT: strd r1, r1, [r0]
249 ; CHECK-NEXT: ldrb r1, [r0, #23]
250 ; CHECK-NEXT: lsls r1, r1, #24
251 ; CHECK-NEXT: str r1, [r0, #20]
254 %bf.load = load i192, ptr %x, align 8
255 %bf.clear4 = and i192 %bf.load, -24519928653854221733733552434404946937899825954937634816
256 store i192 %bf.clear4, ptr %x, align 8
261 define i32 @ashr_demand_bottom3(i64 %x) {
262 ; CHECK-MVE-LABEL: ashr_demand_bottom3:
263 ; CHECK-MVE: @ %bb.0: @ %entry
264 ; CHECK-MVE-NEXT: lsrl r0, r1, #3
265 ; CHECK-MVE-NEXT: bx lr
267 ; CHECK-NON-MVE-LABEL: ashr_demand_bottom3:
268 ; CHECK-NON-MVE: @ %bb.0: @ %entry
269 ; CHECK-NON-MVE-NEXT: lsrs r0, r0, #3
270 ; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #29
271 ; CHECK-NON-MVE-NEXT: bx lr
273 %shr = ashr i64 %x, 3
274 %t = trunc i64 %shr to i32
278 define i32 @lshr_demand_bottom3(i64 %x) {
279 ; CHECK-MVE-LABEL: lshr_demand_bottom3:
280 ; CHECK-MVE: @ %bb.0: @ %entry
281 ; CHECK-MVE-NEXT: lsrl r0, r1, #3
282 ; CHECK-MVE-NEXT: bx lr
284 ; CHECK-NON-MVE-LABEL: lshr_demand_bottom3:
285 ; CHECK-NON-MVE: @ %bb.0: @ %entry
286 ; CHECK-NON-MVE-NEXT: lsrs r0, r0, #3
287 ; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #29
288 ; CHECK-NON-MVE-NEXT: bx lr
290 %shr = lshr i64 %x, 3
291 %t = trunc i64 %shr to i32
295 define i32 @lsl_demand_bottom3(i64 %x) {
296 ; CHECK-LABEL: lsl_demand_bottom3:
297 ; CHECK: @ %bb.0: @ %entry
298 ; CHECK-NEXT: lsls r0, r0, #3
302 %t = trunc i64 %shr to i32
307 define i32 @ashr_demand_bottom31(i64 %x) {
308 ; CHECK-MVE-LABEL: ashr_demand_bottom31:
309 ; CHECK-MVE: @ %bb.0: @ %entry
310 ; CHECK-MVE-NEXT: lsrl r0, r1, #31
311 ; CHECK-MVE-NEXT: bx lr
313 ; CHECK-NON-MVE-LABEL: ashr_demand_bottom31:
314 ; CHECK-NON-MVE: @ %bb.0: @ %entry
315 ; CHECK-NON-MVE-NEXT: lsrs r0, r0, #31
316 ; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #1
317 ; CHECK-NON-MVE-NEXT: bx lr
319 %shr = ashr i64 %x, 31
320 %t = trunc i64 %shr to i32
324 define i32 @lshr_demand_bottom31(i64 %x) {
325 ; CHECK-MVE-LABEL: lshr_demand_bottom31:
326 ; CHECK-MVE: @ %bb.0: @ %entry
327 ; CHECK-MVE-NEXT: lsrl r0, r1, #31
328 ; CHECK-MVE-NEXT: bx lr
330 ; CHECK-NON-MVE-LABEL: lshr_demand_bottom31:
331 ; CHECK-NON-MVE: @ %bb.0: @ %entry
332 ; CHECK-NON-MVE-NEXT: lsrs r0, r0, #31
333 ; CHECK-NON-MVE-NEXT: orr.w r0, r0, r1, lsl #1
334 ; CHECK-NON-MVE-NEXT: bx lr
336 %shr = lshr i64 %x, 31
337 %t = trunc i64 %shr to i32
341 define i32 @lsl_demand_bottom31(i64 %x) {
342 ; CHECK-LABEL: lsl_demand_bottom31:
343 ; CHECK: @ %bb.0: @ %entry
344 ; CHECK-NEXT: lsls r0, r0, #31
347 %shr = shl i64 %x, 31
348 %t = trunc i64 %shr to i32
353 define i32 @ashr_demand_bottom32(i64 %x) {
354 ; CHECK-LABEL: ashr_demand_bottom32:
355 ; CHECK: @ %bb.0: @ %entry
356 ; CHECK-NEXT: mov r0, r1
359 %shr = ashr i64 %x, 32
360 %t = trunc i64 %shr to i32
364 define i32 @lshr_demand_bottom32(i64 %x) {
365 ; CHECK-LABEL: lshr_demand_bottom32:
366 ; CHECK: @ %bb.0: @ %entry
367 ; CHECK-NEXT: mov r0, r1
370 %shr = lshr i64 %x, 32
371 %t = trunc i64 %shr to i32
375 define i32 @lsl_demand_bottom32(i64 %x) {
376 ; CHECK-LABEL: lsl_demand_bottom32:
377 ; CHECK: @ %bb.0: @ %entry
378 ; CHECK-NEXT: movs r0, #0
381 %shr = shl i64 %x, 32
382 %t = trunc i64 %shr to i32
387 define i32 @ashr_demand_bottom44(i64 %x) {
388 ; CHECK-LABEL: ashr_demand_bottom44:
389 ; CHECK: @ %bb.0: @ %entry
390 ; CHECK-NEXT: asrs r0, r1, #12
393 %shr = ashr i64 %x, 44
394 %t = trunc i64 %shr to i32
398 define i32 @lshr_demand_bottom44(i64 %x) {
399 ; CHECK-LABEL: lshr_demand_bottom44:
400 ; CHECK: @ %bb.0: @ %entry
401 ; CHECK-NEXT: lsrs r0, r1, #12
404 %shr = lshr i64 %x, 44
405 %t = trunc i64 %shr to i32
409 define i32 @lsl_demand_bottom44(i64 %x) {
410 ; CHECK-LABEL: lsl_demand_bottom44:
411 ; CHECK: @ %bb.0: @ %entry
412 ; CHECK-NEXT: movs r0, #0
415 %shr = shl i64 %x, 44
416 %t = trunc i64 %shr to i32
421 define i32 @ashr_demand_bottommask(i64 %x) {
422 ; CHECK-LABEL: ashr_demand_bottommask:
423 ; CHECK: @ %bb.0: @ %entry
424 ; CHECK-NEXT: lsls r0, r1, #1
427 %shr = ashr i64 %x, 31
428 %t = trunc i64 %shr to i32
433 define i32 @lshr_demand_bottommask(i64 %x) {
434 ; CHECK-LABEL: lshr_demand_bottommask:
435 ; CHECK: @ %bb.0: @ %entry
436 ; CHECK-NEXT: lsls r0, r1, #1
439 %shr = lshr i64 %x, 31
440 %t = trunc i64 %shr to i32
445 define i32 @lsl_demand_bottommask(i64 %x) {
446 ; CHECK-LABEL: lsl_demand_bottommask:
447 ; CHECK: @ %bb.0: @ %entry
448 ; CHECK-NEXT: lsls r0, r0, #31
451 %shr = shl i64 %x, 31
452 %t = trunc i64 %shr to i32
457 define i32 @ashr_demand_bottommask2(i64 %x) {
458 ; CHECK-LABEL: ashr_demand_bottommask2:
459 ; CHECK: @ %bb.0: @ %entry
460 ; CHECK-NEXT: mvn r0, #2
461 ; CHECK-NEXT: and.w r0, r0, r1, lsl #1
464 %shr = ashr i64 %x, 31
465 %t = trunc i64 %shr to i32
470 define i32 @lshr_demand_bottommask2(i64 %x) {
471 ; CHECK-LABEL: lshr_demand_bottommask2:
472 ; CHECK: @ %bb.0: @ %entry
473 ; CHECK-NEXT: mvn r0, #2
474 ; CHECK-NEXT: and.w r0, r0, r1, lsl #1
477 %shr = lshr i64 %x, 31
478 %t = trunc i64 %shr to i32
483 define i32 @lsl_demand_bottommask2(i64 %x) {
484 ; CHECK-LABEL: lsl_demand_bottommask2:
485 ; CHECK: @ %bb.0: @ %entry
486 ; CHECK-NEXT: lsls r0, r0, #31
489 %shr = shl i64 %x, 31
490 %t = trunc i64 %shr to i32
495 define i32 @lsl_demand_topmask(i64 %x) {
496 ; CHECK-LABEL: lsl_demand_topmask:
497 ; CHECK: @ %bb.0: @ %entry
498 ; CHECK-NEXT: ubfx r0, r0, #1, #28
502 %a = and i64 %sh, 1152921500311879680 ;0x0fffffff00000000
504 %t = trunc i64 %l to i32