1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=aarch64-- | FileCheck %s
4 ; Check that building up a vector w/ only one non-zero lane initializes
7 define <8 x i8> @v8i8z(i8 %t, i8 %s) nounwind {
10 ; CHECK-NEXT: movi v0.2d, #0000000000000000
11 ; CHECK-NEXT: mov v0.b[7], w1
12 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
14 %v = insertelement <8 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 undef>, i8 %s, i32 7
18 define <16 x i8> @v16i8z(i8 %t, i8 %s) nounwind {
19 ; CHECK-LABEL: v16i8z:
21 ; CHECK-NEXT: movi v0.2d, #0000000000000000
22 ; CHECK-NEXT: mov v0.b[15], w1
24 %v = insertelement <16 x i8> <i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 undef>, i8 %s, i32 15
28 define <4 x i16> @v4i16z(i16 %t, i16 %s) nounwind {
29 ; CHECK-LABEL: v4i16z:
31 ; CHECK-NEXT: movi v0.2d, #0000000000000000
32 ; CHECK-NEXT: mov v0.h[3], w1
33 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
35 %v = insertelement <4 x i16> <i16 0, i16 0, i16 0, i16 undef>, i16 %s, i32 3
39 define <8 x i16> @v8i16z(i16 %t, i16 %s) nounwind {
40 ; CHECK-LABEL: v8i16z:
42 ; CHECK-NEXT: movi v0.2d, #0000000000000000
43 ; CHECK-NEXT: mov v0.h[7], w1
45 %v = insertelement <8 x i16> <i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 0, i16 undef>, i16 %s, i32 7
49 define <2 x i32> @v2i32z(i32 %t, i32 %s) nounwind {
50 ; CHECK-LABEL: v2i32z:
52 ; CHECK-NEXT: movi v0.2d, #0000000000000000
53 ; CHECK-NEXT: mov v0.s[1], w1
54 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
56 %v = insertelement <2 x i32> <i32 0, i32 undef>, i32 %s, i32 1
60 define <4 x i32> @v4i32z(i32 %t, i32 %s) nounwind {
61 ; CHECK-LABEL: v4i32z:
63 ; CHECK-NEXT: movi v0.2d, #0000000000000000
64 ; CHECK-NEXT: mov v0.s[3], w1
66 %v = insertelement <4 x i32> <i32 0, i32 0, i32 0, i32 undef>, i32 %s, i32 3
70 define <2 x i64> @v2i64z(i64 %t, i64 %s) nounwind {
71 ; CHECK-LABEL: v2i64z:
73 ; CHECK-NEXT: movi v0.2d, #0000000000000000
74 ; CHECK-NEXT: mov v0.d[1], x1
76 %v = insertelement <2 x i64> <i64 0, i64 undef>, i64 %s, i32 1
80 define <2 x float> @v2f32z(float %t, float %s) nounwind {
81 ; CHECK-LABEL: v2f32z:
83 ; CHECK-NEXT: movi d0, #0000000000000000
84 ; CHECK-NEXT: // kill: def $s1 killed $s1 def $q1
85 ; CHECK-NEXT: mov v0.s[1], v1.s[0]
86 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
88 %v = insertelement <2 x float> <float 0.0, float undef>, float %s, i32 1
92 define <4 x float> @v4f32z(float %t, float %s) nounwind {
93 ; CHECK-LABEL: v4f32z:
95 ; CHECK-NEXT: movi v0.2d, #0000000000000000
96 ; CHECK-NEXT: // kill: def $s1 killed $s1 def $q1
97 ; CHECK-NEXT: mov v0.s[3], v1.s[0]
99 %v = insertelement <4 x float> <float 0.0, float 0.0, float 0.0, float undef>, float %s, i32 3
103 define <2 x double> @v2f64z(double %t, double %s) nounwind {
104 ; CHECK-LABEL: v2f64z:
106 ; CHECK-NEXT: movi v0.2d, #0000000000000000
107 ; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1
108 ; CHECK-NEXT: mov v0.d[1], v1.d[0]
110 %v = insertelement <2 x double> <double 0.0, double undef>, double %s, i32 1
114 ; Check that building up a vector w/ only one non-ones lane initializes
117 define <8 x i8> @v8i8m(i8 %t, i8 %s) nounwind {
118 ; CHECK-LABEL: v8i8m:
120 ; CHECK-NEXT: movi v0.2d, #0xffffffffffffffff
121 ; CHECK-NEXT: mov v0.b[7], w1
122 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
124 %v = insertelement <8 x i8> <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 undef>, i8 %s, i32 7
128 define <16 x i8> @v16i8m(i8 %t, i8 %s) nounwind {
129 ; CHECK-LABEL: v16i8m:
131 ; CHECK-NEXT: movi v0.2d, #0xffffffffffffffff
132 ; CHECK-NEXT: mov v0.b[15], w1
134 %v = insertelement <16 x i8> <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 undef>, i8 %s, i32 15
138 define <4 x i16> @v4i16m(i16 %t, i16 %s) nounwind {
139 ; CHECK-LABEL: v4i16m:
141 ; CHECK-NEXT: movi v0.2d, #0xffffffffffffffff
142 ; CHECK-NEXT: mov v0.h[3], w1
143 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
145 %v = insertelement <4 x i16> <i16 -1, i16 -1, i16 -1, i16 undef>, i16 %s, i32 3
149 define <8 x i16> @v8i16m(i16 %t, i16 %s) nounwind {
150 ; CHECK-LABEL: v8i16m:
152 ; CHECK-NEXT: movi v0.2d, #0xffffffffffffffff
153 ; CHECK-NEXT: mov v0.h[7], w1
155 %v = insertelement <8 x i16> <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 undef>, i16 %s, i32 7
159 define <2 x i32> @v2i32m(i32 %t, i32 %s) nounwind {
160 ; CHECK-LABEL: v2i32m:
162 ; CHECK-NEXT: movi v0.2d, #0xffffffffffffffff
163 ; CHECK-NEXT: mov v0.s[1], w1
164 ; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
166 %v = insertelement <2 x i32> <i32 -1, i32 undef>, i32 %s, i32 1
170 define <4 x i32> @v4i32m(i32 %t, i32 %s) nounwind {
171 ; CHECK-LABEL: v4i32m:
173 ; CHECK-NEXT: movi v0.2d, #0xffffffffffffffff
174 ; CHECK-NEXT: mov v0.s[3], w1
176 %v = insertelement <4 x i32> <i32 -1, i32 -1, i32 -1, i32 undef>, i32 %s, i32 3
180 define <2 x i64> @v2i64m(i64 %t, i64 %s) nounwind {
181 ; CHECK-LABEL: v2i64m:
183 ; CHECK-NEXT: movi v0.2d, #0xffffffffffffffff
184 ; CHECK-NEXT: mov v0.d[1], x1
186 %v = insertelement <2 x i64> <i64 -1, i64 undef>, i64 %s, i32 1
190 ; Check that building up a vector w/ some constants initializes efficiently.
192 define void @v8i8st(ptr %p, i8 %s) nounwind {
193 ; CHECK-LABEL: v8i8st:
195 ; CHECK-NEXT: movi v0.8b, #1
196 ; CHECK-NEXT: mov v0.b[7], w1
197 ; CHECK-NEXT: str d0, [x0]
199 %v = insertelement <8 x i8> <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 undef>, i8 %s, i32 7
200 store <8 x i8> %v, ptr %p, align 8
204 define void @v16i8st(ptr %p, i8 %s) nounwind {
205 ; CHECK-LABEL: v16i8st:
207 ; CHECK-NEXT: movi v0.16b, #128
208 ; CHECK-NEXT: mov v0.b[15], w1
209 ; CHECK-NEXT: str q0, [x0]
211 %v = insertelement <16 x i8> <i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 -128, i8 undef>, i8 %s, i32 15
212 store <16 x i8> %v, ptr %p, align 16
216 define void @v4i16st(ptr %p, i16 %s) nounwind {
217 ; CHECK-LABEL: v4i16st:
219 ; CHECK-NEXT: movi v0.4h, #85, lsl #8
220 ; CHECK-NEXT: mov v0.h[3], w1
221 ; CHECK-NEXT: str d0, [x0]
223 %v = insertelement <4 x i16> <i16 21760, i16 21760, i16 21760, i16 undef>, i16 %s, i32 3
224 store <4 x i16> %v, ptr %p, align 8
228 define void @v8i16st(ptr %p, i16 %s) nounwind {
229 ; CHECK-LABEL: v8i16st:
231 ; CHECK-NEXT: mvni v0.8h, #85, lsl #8
232 ; CHECK-NEXT: mov v0.h[7], w1
233 ; CHECK-NEXT: str q0, [x0]
235 %v = insertelement <8 x i16> <i16 -21761, i16 -21761, i16 -21761, i16 -21761, i16 -21761, i16 -21761, i16 -21761, i16 undef>, i16 %s, i32 7
236 store <8 x i16> %v, ptr %p, align 16
240 define void @v2i32st(ptr %p, i32 %s) nounwind {
241 ; CHECK-LABEL: v2i32st:
243 ; CHECK-NEXT: movi v0.2s, #15, lsl #16
244 ; CHECK-NEXT: mov v0.s[1], w1
245 ; CHECK-NEXT: str d0, [x0]
247 %v = insertelement <2 x i32> <i32 983040, i32 undef>, i32 %s, i32 1
248 store <2 x i32> %v, ptr %p, align 8
252 define void @v4i32st(ptr %p, i32 %s) nounwind {
253 ; CHECK-LABEL: v4i32st:
255 ; CHECK-NEXT: movi v0.4s, #248, msl #16
256 ; CHECK-NEXT: mov v0.s[3], w1
257 ; CHECK-NEXT: str q0, [x0]
259 %v = insertelement <4 x i32> <i32 16318463, i32 16318463, i32 16318463, i32 undef>, i32 %s, i32 3
260 store <4 x i32> %v, ptr %p, align 16
264 define void @v2i64st(ptr %p, i64 %s) nounwind {
265 ; CHECK-LABEL: v2i64st:
267 ; CHECK-NEXT: fmov v0.2d, #-2.00000000
268 ; CHECK-NEXT: mov v0.d[1], x1
269 ; CHECK-NEXT: str q0, [x0]
271 %v = insertelement <2 x i64> <i64 13835058055282163712, i64 undef>, i64 %s, i32 1
272 store <2 x i64> %v, ptr %p, align 16
276 define void @v2f32st(ptr %p, float %s) nounwind {
277 ; CHECK-LABEL: v2f32st:
279 ; CHECK-NEXT: movi v1.2s, #64, lsl #24
280 ; CHECK-NEXT: // kill: def $s0 killed $s0 def $q0
281 ; CHECK-NEXT: mov v1.s[1], v0.s[0]
282 ; CHECK-NEXT: str d1, [x0]
284 %v = insertelement <2 x float> <float 2.0, float undef>, float %s, i32 1
285 store <2 x float> %v, ptr %p, align 8
289 define void @v4f32st(ptr %p, float %s) nounwind {
290 ; CHECK-LABEL: v4f32st:
292 ; CHECK-NEXT: movi v1.4s, #192, lsl #24
293 ; CHECK-NEXT: // kill: def $s0 killed $s0 def $q0
294 ; CHECK-NEXT: mov v1.s[3], v0.s[0]
295 ; CHECK-NEXT: str q1, [x0]
297 %v = insertelement <4 x float> <float -2.0, float -2.0, float -2.0, float undef>, float %s, i32 3
298 store <4 x float> %v, ptr %p, align 16
302 define void @v2f64st(ptr %p, double %s) nounwind {
303 ; CHECK-LABEL: v2f64st:
305 ; CHECK-NEXT: fmov v1.2d, #2.00000000
306 ; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
307 ; CHECK-NEXT: mov v1.d[1], v0.d[0]
308 ; CHECK-NEXT: str q1, [x0]
310 %v = insertelement <2 x double> <double 2.0, double undef>, double %s, i32 1
311 store <2 x double> %v, ptr %p, align 16
315 ; In this test the illegal type has a preferred alignment greater than the
316 ; stack alignment, that gets reduced to the alignment of a broken down
318 define <32 x i8> @test_lanex_32xi8(<32 x i8> %a, i32 %x) {
319 ; CHECK-LABEL: test_lanex_32xi8:
321 ; CHECK-NEXT: // kill: def $w0 killed $w0 def $x0
322 ; CHECK-NEXT: stp q0, q1, [sp, #-32]!
323 ; CHECK-NEXT: .cfi_def_cfa_offset 32
324 ; CHECK-NEXT: and x8, x0, #0x1f
325 ; CHECK-NEXT: mov x9, sp
326 ; CHECK-NEXT: mov w10, #30 // =0x1e
327 ; CHECK-NEXT: strb w10, [x9, x8]
328 ; CHECK-NEXT: ldp q0, q1, [sp], #32
330 %b = insertelement <32 x i8> %a, i8 30, i32 %x