[ARM] Cortex-M4 schedule additions
[llvm-complete.git] / test / CodeGen / ARM / shift_parts.ll
blob9bc77d585bf95f8338271c1d19d5af47405bbe1d
1 ; RUN: llc --verify-machineinstrs -mtriple=thumbv8.1-m.main-none-eabi -mattr=+mve %s -o - | FileCheck %s -check-prefix=CHECK --check-prefix=CHECK-MVE
2 ; RUN: llc --verify-machineinstrs -mtriple=thumbv8.1-m.main-none-eabi %s -o - | FileCheck %s -check-prefix=CHECK --check-prefix=CHECK-NON-MVE
4 define i64 @shift_left_reg(i64 %x, i64 %y) {
5 ; CHECK-MVE-LABEL: shift_left_reg:
6 ; CHECK-MVE:       @ %bb.0: @ %entry
7 ; CHECK-MVE-NEXT:    lsll r0, r1, r2
8 ; CHECK-MVE-NEXT:    bx lr
10 ; CHECK-NON-MVE-LABEL: shift_left_reg:
11 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
12 ; CHECK-NON-MVE-NEXT:    .save {r7, lr}
13 ; CHECK-NON-MVE-NEXT:    push {r7, lr}
14 ; CHECK-NON-MVE-NEXT:    bl __aeabi_llsl
15 ; CHECK-NON-MVE-NEXT:    pop {r7}
16 ; CHECK-NON-MVE-NEXT:    pop {r2}
17 ; CHECK-NON-MVE-NEXT:    bx r2
18 entry:
19   %shl = shl i64 %x, %y
20   ret i64 %shl
23 define i64 @shift_left_imm(i64 %x) {
24 ; CHECK-MVE-LABEL: shift_left_imm:
25 ; CHECK-MVE:       @ %bb.0: @ %entry
26 ; CHECK-MVE-NEXT:    lsll r0, r1, #3
27 ; CHECK-MVE-NEXT:    bx lr
29 ; CHECK-NON-MVE-LABEL: shift_left_imm:
30 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
31 ; CHECK-NON-MVE-NEXT:    lsrs r2, r0, #29
32 ; CHECK-NON-MVE-NEXT:    lsls r1, r1, #3
33 ; CHECK-NON-MVE-NEXT:    adds r1, r1, r2
34 ; CHECK-NON-MVE-NEXT:    lsls r0, r0, #3
35 ; CHECK-NON-MVE-NEXT:    bx lr
36 entry:
37   %shl = shl i64 %x, 3
38   ret i64 %shl
41 define i64 @shift_left_imm_big(i64 %x) {
42 ; CHECK-LABEL: shift_left_imm_big:
43 ; CHECK:       @ %bb.0: @ %entry
44 ; CHECK-NEXT:    lsls r1, r0, #16
45 ; CHECK-NEXT:    movs r0, #0
46 ; CHECK-NEXT:    bx lr
47 entry:
48   %shl = shl i64 %x, 48
49   ret i64 %shl
52 define i64 @shift_left_imm_big2(i64 %x) {
53 ; CHECK-MVE-LABEL: shift_left_imm_big2:
54 ; CHECK-MVE:       @ %bb.0: @ %entry
55 ; CHECK-MVE-NEXT:    mov r1, r0
56 ; CHECK-MVE-NEXT:    movs r0, #0
57 ; CHECK-MVE-NEXT:    bx lr
59 ; CHECK-NON-MVE-LABEL: shift_left_imm_big2:
60 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
61 ; CHECK-NON-MVE-NEXT:    movs r1, r0
62 ; CHECK-NON-MVE-NEXT:    movs r0, #0
63 ; CHECK-NON-MVE-NEXT:    bx lr
64 entry:
65   %shl = shl i64 %x, 32
66   ret i64 %shl
69 define i64 @shift_left_imm_big3(i64 %x) {
70 ; CHECK-LABEL: shift_left_imm_big3:
71 ; CHECK:       @ %bb.0: @ %entry
72 ; CHECK-NEXT:    lsls r1, r0, #1
73 ; CHECK-NEXT:    movs r0, #0
74 ; CHECK-NEXT:    bx lr
75 entry:
76   %shl = shl i64 %x, 33
77   ret i64 %shl
80 define i64 @shift_right_reg(i64 %x, i64 %y) {
81 ; CHECK-MVE-LABEL: shift_right_reg:
82 ; CHECK-MVE:       @ %bb.0: @ %entry
83 ; CHECK-MVE-NEXT:    rsbs r2, r2, #0
84 ; CHECK-MVE-NEXT:    lsll r0, r1, r2
85 ; CHECK-MVE-NEXT:    bx lr
87 ; CHECK-NON-MVE-LABEL: shift_right_reg:
88 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
89 ; CHECK-NON-MVE-NEXT:    .save {r7, lr}
90 ; CHECK-NON-MVE-NEXT:    push {r7, lr}
91 ; CHECK-NON-MVE-NEXT:    bl __aeabi_llsr
92 ; CHECK-NON-MVE-NEXT:    pop {r7}
93 ; CHECK-NON-MVE-NEXT:    pop {r2}
94 ; CHECK-NON-MVE-NEXT:    bx r2
95 entry:
96   %shr = lshr i64 %x, %y
97   ret i64 %shr
100 define i64 @shift_right_imm(i64 %x) {
101 ; CHECK-MVE-LABEL: shift_right_imm:
102 ; CHECK-MVE:       @ %bb.0: @ %entry
103 ; CHECK-MVE-NEXT:    lsrl r0, r1, #3
104 ; CHECK-MVE-NEXT:    bx lr
106 ; CHECK-NON-MVE-LABEL: shift_right_imm:
107 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
108 ; CHECK-NON-MVE-NEXT:    lsls r2, r1, #29
109 ; CHECK-NON-MVE-NEXT:    lsrs r0, r0, #3
110 ; CHECK-NON-MVE-NEXT:    adds r0, r0, r2
111 ; CHECK-NON-MVE-NEXT:    lsrs r1, r1, #3
112 ; CHECK-NON-MVE-NEXT:    bx lr
113 entry:
114   %shr = lshr i64 %x, 3
115   ret i64 %shr
118 define i64 @shift_right_imm_big(i64 %x) {
119 ; CHECK-LABEL: shift_right_imm_big:
120 ; CHECK:       @ %bb.0: @ %entry
121 ; CHECK-NEXT:    lsrs r0, r1, #16
122 ; CHECK-NEXT:    movs r1, #0
123 ; CHECK-NEXT:    bx lr
124 entry:
125   %shr = lshr i64 %x, 48
126   ret i64 %shr
129 define i64 @shift_right_imm_big2(i64 %x) {
130 ; CHECK-MVE-LABEL: shift_right_imm_big2:
131 ; CHECK-MVE:       @ %bb.0: @ %entry
132 ; CHECK-MVE-NEXT:    mov r0, r1
133 ; CHECK-MVE-NEXT:    movs r1, #0
134 ; CHECK-MVE-NEXT:    bx lr
136 ; CHECK-NON-MVE-LABEL: shift_right_imm_big2:
137 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
138 ; CHECK-NON-MVE-NEXT:    movs r0, r1
139 ; CHECK-NON-MVE-NEXT:    movs r1, #0
140 ; CHECK-NON-MVE-NEXT:    bx lr
141 entry:
142   %shr = lshr i64 %x, 32
143   ret i64 %shr
146 define i64 @shift_right_imm_big3(i64 %x) {
147 ; CHECK-LABEL: shift_right_imm_big3:
148 ; CHECK:       @ %bb.0: @ %entry
149 ; CHECK-NEXT:    lsrs r0, r1, #1
150 ; CHECK-NEXT:    movs r1, #0
151 ; CHECK-NEXT:    bx lr
152 entry:
153   %shr = lshr i64 %x, 33
154   ret i64 %shr
157 define i64 @shift_arithmetic_right_reg(i64 %x, i64 %y) {
158 ; CHECK-MVE-LABEL: shift_arithmetic_right_reg:
159 ; CHECK-MVE:       @ %bb.0: @ %entry
160 ; CHECK-MVE-NEXT:    asrl r0, r1, r2
161 ; CHECK-MVE-NEXT:    bx lr
163 ; CHECK-NON-MVE-LABEL: shift_arithmetic_right_reg:
164 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
165 ; CHECK-NON-MVE-NEXT:    .save {r7, lr}
166 ; CHECK-NON-MVE-NEXT:    push {r7, lr}
167 ; CHECK-NON-MVE-NEXT:    bl __aeabi_lasr
168 ; CHECK-NON-MVE-NEXT:    pop {r7}
169 ; CHECK-NON-MVE-NEXT:    pop {r2}
170 ; CHECK-NON-MVE-NEXT:    bx r2
171 entry:
172   %shr = ashr i64 %x, %y
173   ret i64 %shr
176 define i64 @shift_arithmetic_right_imm(i64 %x) {
177 ; CHECK-MVE-LABEL: shift_arithmetic_right_imm:
178 ; CHECK-MVE:       @ %bb.0: @ %entry
179 ; CHECK-MVE-NEXT:    asrl r0, r1, #3
180 ; CHECK-MVE-NEXT:    bx lr
182 ; CHECK-NON-MVE-LABEL: shift_arithmetic_right_imm:
183 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
184 ; CHECK-NON-MVE-NEXT:    lsls r2, r1, #29
185 ; CHECK-NON-MVE-NEXT:    lsrs r0, r0, #3
186 ; CHECK-NON-MVE-NEXT:    adds r0, r0, r2
187 ; CHECK-NON-MVE-NEXT:    asrs r1, r1, #3
188 ; CHECK-NON-MVE-NEXT:    bx lr
189 entry:
190   %shr = ashr i64 %x, 3
191   ret i64 %shr
194 %struct.bar = type { i16, i8, [5 x i8] }
196 define arm_aapcs_vfpcc void @fn1(%struct.bar* nocapture %a) {
197 ; CHECK-MVE-LABEL: fn1:
198 ; CHECK-MVE:       @ %bb.0: @ %entry
199 ; CHECK-MVE-NEXT:    ldr r2, [r0, #4]
200 ; CHECK-MVE-NEXT:    movs r1, #0
201 ; CHECK-MVE-NEXT:    lsll r2, r1, #8
202 ; CHECK-MVE-NEXT:    strb r1, [r0, #7]
203 ; CHECK-MVE-NEXT:    str.w r2, [r0, #3]
204 ; CHECK-MVE-NEXT:    bx lr
206 ; CHECK-NON-MVE-LABEL: fn1:
207 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
208 ; CHECK-NON-MVE-NEXT:    ldr r1, [r0, #4]
209 ; CHECK-NON-MVE-NEXT:    lsls r2, r1, #8
210 ; CHECK-NON-MVE-NEXT:    movs r3, #3
211 ; CHECK-NON-MVE-NEXT:    str r2, [r0, r3]
212 ; CHECK-NON-MVE-NEXT:    adds r0, r0, #3
213 ; CHECK-NON-MVE-NEXT:    lsrs r1, r1, #24
214 ; CHECK-NON-MVE-NEXT:    strb r1, [r0, #4]
215 ; CHECK-NON-MVE-NEXT:    bx lr
216 entry:
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
222   ret void
225 %struct.a = type { i96 }
227 define void @lsll_128bit_shift(%struct.a* nocapture %x) local_unnamed_addr #0 {
228 ; CHECK-MVE-LABEL: lsll_128bit_shift:
229 ; CHECK-MVE:       @ %bb.0: @ %entry
230 ; CHECK-MVE-NEXT:    movs r1, #0
231 ; CHECK-MVE-NEXT:    strd r1, r1, [r0]
232 ; CHECK-MVE-NEXT:    str r1, [r0, #8]
233 ; CHECK-MVE-NEXT:    bx lr
235 ; CHECK-NON-MVE-LABEL: lsll_128bit_shift:
236 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
237 ; CHECK-NON-MVE-NEXT:    movs r1, #0
238 ; CHECK-NON-MVE-NEXT:    str r1, [r0]
239 ; CHECK-NON-MVE-NEXT:    str r1, [r0, #4]
240 ; CHECK-NON-MVE-NEXT:    str r1, [r0, #8]
241 ; CHECK-NON-MVE-NEXT:    bx lr
242 entry:
243   %0 = bitcast %struct.a* %x to i128*
244   %bf.load = load i128, i128* %0, align 8
245   %bf.clear4 = and i128 %bf.load, -79228162514264337593543950336
246   store i128 %bf.clear4, i128* %0, align 8
247   ret void
250 %struct.b = type { i184 }
252 define void @lsll_256bit_shift(%struct.b* nocapture %x) local_unnamed_addr #0 {
253 ; CHECK-MVE-LABEL: lsll_256bit_shift:
254 ; CHECK-MVE:       @ %bb.0: @ %entry
255 ; CHECK-MVE-NEXT:    movs r1, #0
256 ; CHECK-MVE-NEXT:    str r1, [r0, #16]
257 ; CHECK-MVE-NEXT:    strd r1, r1, [r0, #8]
258 ; CHECK-MVE-NEXT:    strd r1, r1, [r0]
259 ; CHECK-MVE-NEXT:    ldrb r1, [r0, #23]
260 ; CHECK-MVE-NEXT:    lsls r1, r1, #24
261 ; CHECK-MVE-NEXT:    str r1, [r0, #20]
262 ; CHECK-MVE-NEXT:    bx lr
264 ; CHECK-NON-MVE-LABEL: lsll_256bit_shift:
265 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
266 ; CHECK-NON-MVE-NEXT:    movs r1, #0
267 ; CHECK-NON-MVE-NEXT:    str r1, [r0, #16]
268 ; CHECK-NON-MVE-NEXT:    str r1, [r0, #8]
269 ; CHECK-NON-MVE-NEXT:    str r1, [r0, #12]
270 ; CHECK-NON-MVE-NEXT:    str r1, [r0]
271 ; CHECK-NON-MVE-NEXT:    str r1, [r0, #4]
272 ; CHECK-NON-MVE-NEXT:    ldrb r1, [r0, #23]
273 ; CHECK-NON-MVE-NEXT:    lsls r1, r1, #24
274 ; CHECK-NON-MVE-NEXT:    str r1, [r0, #20]
275 ; CHECK-NON-MVE-NEXT:    bx lr
276 entry:
277   %0 = bitcast %struct.b* %x to i192*
278   %bf.load = load i192, i192* %0, align 8
279   %bf.clear4 = and i192 %bf.load, -24519928653854221733733552434404946937899825954937634816
280   store i192 %bf.clear4, i192* %0, align 8
281   ret void