xref: /llvm-project/llvm/test/CodeGen/Thumb2/shift_parts.ll (revision b5b663aac17415625340eb29c8010832bfc4c21c)
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
4
5define 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
10;
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
24entry:
25  %shl = shl i64 %x, %y
26  ret i64 %shl
27}
28
29define 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
34;
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
41entry:
42  %shl = shl i64 %x, 3
43  ret i64 %shl
44}
45
46define 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
51; CHECK-NEXT:    bx lr
52entry:
53  %shl = shl i64 %x, 48
54  ret i64 %shl
55}
56
57define 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
62; CHECK-NEXT:    bx lr
63entry:
64  %shl = shl i64 %x, 32
65  ret i64 %shl
66}
67
68define 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
73; CHECK-NEXT:    bx lr
74entry:
75  %shl = shl i64 %x, 33
76  ret i64 %shl
77}
78
79define 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
85;
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
99entry:
100  %shr = lshr i64 %x, %y
101  ret i64 %shr
102}
103
104define 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
109;
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
116entry:
117  %shr = lshr i64 %x, 3
118  ret i64 %shr
119}
120
121define 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
126; CHECK-NEXT:    bx lr
127entry:
128  %shr = lshr i64 %x, 48
129  ret i64 %shr
130}
131
132define 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
137; CHECK-NEXT:    bx lr
138entry:
139  %shr = lshr i64 %x, 32
140  ret i64 %shr
141}
142
143define 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
148; CHECK-NEXT:    bx lr
149entry:
150  %shr = lshr i64 %x, 33
151  ret i64 %shr
152}
153
154define 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
159;
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
174entry:
175  %shr = ashr i64 %x, %y
176  ret i64 %shr
177}
178
179define 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
184;
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
191entry:
192  %shr = ashr i64 %x, 3
193  ret i64 %shr
194}
195
196%struct.bar = type { i16, i8, [5 x i8] }
197
198define 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
207;
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
216entry:
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
221  ret void
222}
223
224%struct.a = type { i96 }
225
226define 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]
232; CHECK-NEXT:    bx lr
233entry:
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
237  ret void
238}
239
240%struct.b = type { i184 }
241
242define 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]
252; CHECK-NEXT:    bx lr
253entry:
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
257  ret void
258}
259
260
261define 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
266;
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
272entry:
273  %shr = ashr i64 %x, 3
274  %t = trunc i64 %shr to i32
275  ret i32 %t
276}
277
278define 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
283;
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
289entry:
290  %shr = lshr i64 %x, 3
291  %t = trunc i64 %shr to i32
292  ret i32 %t
293}
294
295define i32 @lsl_demand_bottom3(i64 %x) {
296; CHECK-LABEL: lsl_demand_bottom3:
297; CHECK:       @ %bb.0: @ %entry
298; CHECK-NEXT:    lsls r0, r0, #3
299; CHECK-NEXT:    bx lr
300entry:
301  %shr = shl i64 %x, 3
302  %t = trunc i64 %shr to i32
303  ret i32 %t
304}
305
306
307define 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
312;
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
318entry:
319  %shr = ashr i64 %x, 31
320  %t = trunc i64 %shr to i32
321  ret i32 %t
322}
323
324define 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
329;
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
335entry:
336  %shr = lshr i64 %x, 31
337  %t = trunc i64 %shr to i32
338  ret i32 %t
339}
340
341define i32 @lsl_demand_bottom31(i64 %x) {
342; CHECK-LABEL: lsl_demand_bottom31:
343; CHECK:       @ %bb.0: @ %entry
344; CHECK-NEXT:    lsls r0, r0, #31
345; CHECK-NEXT:    bx lr
346entry:
347  %shr = shl i64 %x, 31
348  %t = trunc i64 %shr to i32
349  ret i32 %t
350}
351
352
353define i32 @ashr_demand_bottom32(i64 %x) {
354; CHECK-LABEL: ashr_demand_bottom32:
355; CHECK:       @ %bb.0: @ %entry
356; CHECK-NEXT:    mov r0, r1
357; CHECK-NEXT:    bx lr
358entry:
359  %shr = ashr i64 %x, 32
360  %t = trunc i64 %shr to i32
361  ret i32 %t
362}
363
364define i32 @lshr_demand_bottom32(i64 %x) {
365; CHECK-LABEL: lshr_demand_bottom32:
366; CHECK:       @ %bb.0: @ %entry
367; CHECK-NEXT:    mov r0, r1
368; CHECK-NEXT:    bx lr
369entry:
370  %shr = lshr i64 %x, 32
371  %t = trunc i64 %shr to i32
372  ret i32 %t
373}
374
375define i32 @lsl_demand_bottom32(i64 %x) {
376; CHECK-LABEL: lsl_demand_bottom32:
377; CHECK:       @ %bb.0: @ %entry
378; CHECK-NEXT:    movs r0, #0
379; CHECK-NEXT:    bx lr
380entry:
381  %shr = shl i64 %x, 32
382  %t = trunc i64 %shr to i32
383  ret i32 %t
384}
385
386
387define i32 @ashr_demand_bottom44(i64 %x) {
388; CHECK-LABEL: ashr_demand_bottom44:
389; CHECK:       @ %bb.0: @ %entry
390; CHECK-NEXT:    asrs r0, r1, #12
391; CHECK-NEXT:    bx lr
392entry:
393  %shr = ashr i64 %x, 44
394  %t = trunc i64 %shr to i32
395  ret i32 %t
396}
397
398define i32 @lshr_demand_bottom44(i64 %x) {
399; CHECK-LABEL: lshr_demand_bottom44:
400; CHECK:       @ %bb.0: @ %entry
401; CHECK-NEXT:    lsrs r0, r1, #12
402; CHECK-NEXT:    bx lr
403entry:
404  %shr = lshr i64 %x, 44
405  %t = trunc i64 %shr to i32
406  ret i32 %t
407}
408
409define i32 @lsl_demand_bottom44(i64 %x) {
410; CHECK-LABEL: lsl_demand_bottom44:
411; CHECK:       @ %bb.0: @ %entry
412; CHECK-NEXT:    movs r0, #0
413; CHECK-NEXT:    bx lr
414entry:
415  %shr = shl i64 %x, 44
416  %t = trunc i64 %shr to i32
417  ret i32 %t
418}
419
420
421define i32 @ashr_demand_bottommask(i64 %x) {
422; CHECK-LABEL: ashr_demand_bottommask:
423; CHECK:       @ %bb.0: @ %entry
424; CHECK-NEXT:    lsls r0, r1, #1
425; CHECK-NEXT:    bx lr
426entry:
427  %shr = ashr i64 %x, 31
428  %t = trunc i64 %shr to i32
429  %a = and i32 %t, -2
430  ret i32 %a
431}
432
433define i32 @lshr_demand_bottommask(i64 %x) {
434; CHECK-LABEL: lshr_demand_bottommask:
435; CHECK:       @ %bb.0: @ %entry
436; CHECK-NEXT:    lsls r0, r1, #1
437; CHECK-NEXT:    bx lr
438entry:
439  %shr = lshr i64 %x, 31
440  %t = trunc i64 %shr to i32
441  %a = and i32 %t, -2
442  ret i32 %a
443}
444
445define i32 @lsl_demand_bottommask(i64 %x) {
446; CHECK-LABEL: lsl_demand_bottommask:
447; CHECK:       @ %bb.0: @ %entry
448; CHECK-NEXT:    lsls r0, r0, #31
449; CHECK-NEXT:    bx lr
450entry:
451  %shr = shl i64 %x, 31
452  %t = trunc i64 %shr to i32
453  %a = and i32 %t, -2
454  ret i32 %a
455}
456
457define 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
462; CHECK-NEXT:    bx lr
463entry:
464  %shr = ashr i64 %x, 31
465  %t = trunc i64 %shr to i32
466  %a = and i32 %t, -4
467  ret i32 %a
468}
469
470define 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
475; CHECK-NEXT:    bx lr
476entry:
477  %shr = lshr i64 %x, 31
478  %t = trunc i64 %shr to i32
479  %a = and i32 %t, -4
480  ret i32 %a
481}
482
483define i32 @lsl_demand_bottommask2(i64 %x) {
484; CHECK-LABEL: lsl_demand_bottommask2:
485; CHECK:       @ %bb.0: @ %entry
486; CHECK-NEXT:    lsls r0, r0, #31
487; CHECK-NEXT:    bx lr
488entry:
489  %shr = shl i64 %x, 31
490  %t = trunc i64 %shr to i32
491  %a = and i32 %t, -4
492  ret i32 %a
493}
494
495define 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
499; CHECK-NEXT:    bx lr
500entry:
501  %sh = shl i64 %x, 31
502  %a = and i64 %sh, 1152921500311879680 ;0x0fffffff00000000
503  %l = ashr i64 %a, 32
504  %t = trunc i64 %l to i32
505  ret i32 %t
506}
507