[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / test / CodeGen / ARM / shift_parts.ll
bloba3a98e6d25202e2dc934a68f899c6708e8424ec7
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:    lsll r0, r1, #32
56 ; CHECK-MVE-NEXT:    bx lr
58 ; CHECK-NON-MVE-LABEL: shift_left_imm_big2:
59 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
60 ; CHECK-NON-MVE-NEXT:    movs r1, r0
61 ; CHECK-NON-MVE-NEXT:    movs r0, #0
62 ; CHECK-NON-MVE-NEXT:    bx lr
63 entry:
64   %shl = shl i64 %x, 32
65   ret i64 %shl
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
73 ; CHECK-NEXT:    bx lr
74 entry:
75   %shl = shl i64 %x, 33
76   ret i64 %shl
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:    .save {r7, lr}
89 ; CHECK-NON-MVE-NEXT:    push {r7, lr}
90 ; CHECK-NON-MVE-NEXT:    bl __aeabi_llsr
91 ; CHECK-NON-MVE-NEXT:    pop {r7}
92 ; CHECK-NON-MVE-NEXT:    pop {r2}
93 ; CHECK-NON-MVE-NEXT:    bx r2
94 entry:
95   %shr = lshr i64 %x, %y
96   ret i64 %shr
99 define i64 @shift_right_imm(i64 %x) {
100 ; CHECK-MVE-LABEL: shift_right_imm:
101 ; CHECK-MVE:       @ %bb.0: @ %entry
102 ; CHECK-MVE-NEXT:    lsrl r0, r1, #3
103 ; CHECK-MVE-NEXT:    bx lr
105 ; CHECK-NON-MVE-LABEL: shift_right_imm:
106 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
107 ; CHECK-NON-MVE-NEXT:    lsls r2, r1, #29
108 ; CHECK-NON-MVE-NEXT:    lsrs r0, r0, #3
109 ; CHECK-NON-MVE-NEXT:    adds r0, r0, r2
110 ; CHECK-NON-MVE-NEXT:    lsrs r1, r1, #3
111 ; CHECK-NON-MVE-NEXT:    bx lr
112 entry:
113   %shr = lshr i64 %x, 3
114   ret i64 %shr
117 define i64 @shift_right_imm_big(i64 %x) {
118 ; CHECK-LABEL: shift_right_imm_big:
119 ; CHECK:       @ %bb.0: @ %entry
120 ; CHECK-NEXT:    lsrs r0, r1, #16
121 ; CHECK-NEXT:    movs r1, #0
122 ; CHECK-NEXT:    bx lr
123 entry:
124   %shr = lshr i64 %x, 48
125   ret i64 %shr
128 define i64 @shift_right_imm_big2(i64 %x) {
129 ; CHECK-MVE-LABEL: shift_right_imm_big2:
130 ; CHECK-MVE:       @ %bb.0: @ %entry
131 ; CHECK-MVE-NEXT:    lsrl r0, r1, #32
132 ; CHECK-MVE-NEXT:    bx lr
134 ; CHECK-NON-MVE-LABEL: shift_right_imm_big2:
135 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
136 ; CHECK-NON-MVE-NEXT:    movs r0, r1
137 ; CHECK-NON-MVE-NEXT:    movs r1, #0
138 ; CHECK-NON-MVE-NEXT:    bx lr
139 entry:
140   %shr = lshr i64 %x, 32
141   ret i64 %shr
144 define i64 @shift_right_imm_big3(i64 %x) {
145 ; CHECK-LABEL: shift_right_imm_big3:
146 ; CHECK:       @ %bb.0: @ %entry
147 ; CHECK-NEXT:    lsrs r0, r1, #1
148 ; CHECK-NEXT:    movs r1, #0
149 ; CHECK-NEXT:    bx lr
150 entry:
151   %shr = lshr i64 %x, 33
152   ret i64 %shr
155 define i64 @shift_arithmetic_right_reg(i64 %x, i64 %y) {
156 ; CHECK-MVE-LABEL: shift_arithmetic_right_reg:
157 ; CHECK-MVE:       @ %bb.0: @ %entry
158 ; CHECK-MVE-NEXT:    asrl r0, r1, r2
159 ; CHECK-MVE-NEXT:    bx lr
161 ; CHECK-NON-MVE-LABEL: shift_arithmetic_right_reg:
162 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
163 ; CHECK-NON-MVE-NEXT:    .save {r7, lr}
164 ; CHECK-NON-MVE-NEXT:    push {r7, lr}
165 ; CHECK-NON-MVE-NEXT:    bl __aeabi_lasr
166 ; CHECK-NON-MVE-NEXT:    pop {r7}
167 ; CHECK-NON-MVE-NEXT:    pop {r2}
168 ; CHECK-NON-MVE-NEXT:    bx r2
169 entry:
170   %shr = ashr i64 %x, %y
171   ret i64 %shr
174 define i64 @shift_arithmetic_right_imm(i64 %x) {
175 ; CHECK-MVE-LABEL: shift_arithmetic_right_imm:
176 ; CHECK-MVE:       @ %bb.0: @ %entry
177 ; CHECK-MVE-NEXT:    asrl r0, r1, #3
178 ; CHECK-MVE-NEXT:    bx lr
180 ; CHECK-NON-MVE-LABEL: shift_arithmetic_right_imm:
181 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
182 ; CHECK-NON-MVE-NEXT:    lsls r2, r1, #29
183 ; CHECK-NON-MVE-NEXT:    lsrs r0, r0, #3
184 ; CHECK-NON-MVE-NEXT:    adds r0, r0, r2
185 ; CHECK-NON-MVE-NEXT:    asrs r1, r1, #3
186 ; CHECK-NON-MVE-NEXT:    bx lr
187 entry:
188   %shr = ashr i64 %x, 3
189   ret i64 %shr
192 %struct.bar = type { i16, i8, [5 x i8] }
194 define arm_aapcs_vfpcc void @fn1(%struct.bar* nocapture %a) {
195 ; CHECK-MVE-LABEL: fn1:
196 ; CHECK-MVE:       @ %bb.0: @ %entry
197 ; CHECK-MVE-NEXT:    ldr r2, [r0, #4]
198 ; CHECK-MVE-NEXT:    movs r1, #0
199 ; CHECK-MVE-NEXT:    lsll r2, r1, #8
200 ; CHECK-MVE-NEXT:    strb r1, [r0, #7]
201 ; CHECK-MVE-NEXT:    str.w r2, [r0, #3]
202 ; CHECK-MVE-NEXT:    bx lr
204 ; CHECK-NON-MVE-LABEL: fn1:
205 ; CHECK-NON-MVE:       @ %bb.0: @ %entry
206 ; CHECK-NON-MVE-NEXT:    ldr r1, [r0, #4]
207 ; CHECK-NON-MVE-NEXT:    lsls r2, r1, #8
208 ; CHECK-NON-MVE-NEXT:    movs r3, #3
209 ; CHECK-NON-MVE-NEXT:    str r2, [r0, r3]
210 ; CHECK-NON-MVE-NEXT:    adds r0, r0, #3
211 ; CHECK-NON-MVE-NEXT:    lsrs r1, r1, #24
212 ; CHECK-NON-MVE-NEXT:    strb r1, [r0, #4]
213 ; CHECK-NON-MVE-NEXT:    bx lr
214 entry:
215   %carey = getelementptr inbounds %struct.bar, %struct.bar* %a, i32 0, i32 2
216   %0 = bitcast [5 x i8]* %carey to i40*
217   %bf.load = load i40, i40* %0, align 1
218   %bf.clear = and i40 %bf.load, -256
219   store i40 %bf.clear, i40* %0, align 1
220   ret void