1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s
3; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t
4
5; WARN-NOT: warning
6
7define <vscale x 16 x i8> @test_lane0_16xi8(<vscale x 16 x i8> %a) {
8; CHECK-LABEL: test_lane0_16xi8:
9; CHECK:       // %bb.0:
10; CHECK-NEXT:    ptrue p0.b, vl1
11; CHECK-NEXT:    mov w8, #30
12; CHECK-NEXT:    mov z0.b, p0/m, w8
13; CHECK-NEXT:    ret
14  %b = insertelement <vscale x 16 x i8> %a, i8 30, i32 0
15  ret <vscale x 16 x i8> %b
16}
17
18define <vscale x 8 x i16> @test_lane0_8xi16(<vscale x 8 x i16> %a) {
19; CHECK-LABEL: test_lane0_8xi16:
20; CHECK:       // %bb.0:
21; CHECK-NEXT:    ptrue p0.h, vl1
22; CHECK-NEXT:    mov w8, #30
23; CHECK-NEXT:    mov z0.h, p0/m, w8
24; CHECK-NEXT:    ret
25  %b = insertelement <vscale x 8 x i16> %a, i16 30, i32 0
26  ret <vscale x 8 x i16> %b
27}
28
29define <vscale x 4 x i32> @test_lane0_4xi32(<vscale x 4 x i32> %a) {
30; CHECK-LABEL: test_lane0_4xi32:
31; CHECK:       // %bb.0:
32; CHECK-NEXT:    ptrue p0.s, vl1
33; CHECK-NEXT:    mov w8, #30
34; CHECK-NEXT:    mov z0.s, p0/m, w8
35; CHECK-NEXT:    ret
36  %b = insertelement <vscale x 4 x i32> %a, i32 30, i32 0
37  ret <vscale x 4 x i32> %b
38}
39
40define <vscale x 2 x i64> @test_lane0_2xi64(<vscale x 2 x i64> %a) {
41; CHECK-LABEL: test_lane0_2xi64:
42; CHECK:       // %bb.0:
43; CHECK-NEXT:    ptrue p0.d, vl1
44; CHECK-NEXT:    mov w8, #30
45; CHECK-NEXT:    mov z0.d, p0/m, x8
46; CHECK-NEXT:    ret
47  %b = insertelement <vscale x 2 x i64> %a, i64 30, i32 0
48  ret <vscale x 2 x i64> %b
49}
50
51define <vscale x 2 x double> @test_lane0_2xf64(<vscale x 2 x double> %a) {
52; CHECK-LABEL: test_lane0_2xf64:
53; CHECK:       // %bb.0:
54; CHECK-NEXT:    fmov d1, #1.00000000
55; CHECK-NEXT:    ptrue p0.d, vl1
56; CHECK-NEXT:    mov z0.d, p0/m, z1.d
57; CHECK-NEXT:    ret
58  %b = insertelement <vscale x 2 x double> %a, double 1.0, i32 0
59  ret <vscale x 2 x double> %b
60}
61
62define <vscale x 4 x float> @test_lane0_4xf32(<vscale x 4 x float> %a) {
63; CHECK-LABEL: test_lane0_4xf32:
64; CHECK:       // %bb.0:
65; CHECK-NEXT:    fmov s1, #1.00000000
66; CHECK-NEXT:    ptrue p0.s, vl1
67; CHECK-NEXT:    mov z0.s, p0/m, z1.s
68; CHECK-NEXT:    ret
69  %b = insertelement <vscale x 4 x float> %a, float 1.0, i32 0
70  ret <vscale x 4 x float> %b
71}
72
73define <vscale x 8 x half> @test_lane0_8xf16(<vscale x 8 x half> %a) {
74; CHECK-LABEL: test_lane0_8xf16:
75; CHECK:       // %bb.0:
76; CHECK-NEXT:    fmov h1, #1.00000000
77; CHECK-NEXT:    ptrue p0.h, vl1
78; CHECK-NEXT:    mov z0.h, p0/m, z1.h
79; CHECK-NEXT:    ret
80  %b = insertelement <vscale x 8 x half> %a, half 1.0, i32 0
81  ret <vscale x 8 x half> %b
82}
83
84; Undefined lane insert
85define <vscale x 2 x i64> @test_lane4_2xi64(<vscale x 2 x i64> %a) {
86; CHECK-LABEL: test_lane4_2xi64:
87; CHECK:       // %bb.0:
88; CHECK-NEXT:    mov w8, #4
89; CHECK-NEXT:    index z1.d, #0, #1
90; CHECK-NEXT:    ptrue p0.d
91; CHECK-NEXT:    mov z2.d, x8
92; CHECK-NEXT:    cmpeq p0.d, p0/z, z1.d, z2.d
93; CHECK-NEXT:    mov w8, #30
94; CHECK-NEXT:    mov z0.d, p0/m, x8
95; CHECK-NEXT:    ret
96  %b = insertelement <vscale x 2 x i64> %a, i64 30, i32 4
97  ret <vscale x 2 x i64> %b
98}
99
100; Undefined lane insert
101define <vscale x 8 x half> @test_lane9_8xf16(<vscale x 8 x half> %a) {
102; CHECK-LABEL: test_lane9_8xf16:
103; CHECK:       // %bb.0:
104; CHECK-NEXT:    mov w8, #9
105; CHECK-NEXT:    index z1.h, #0, #1
106; CHECK-NEXT:    ptrue p0.h
107; CHECK-NEXT:    mov z2.h, w8
108; CHECK-NEXT:    cmpeq p0.h, p0/z, z1.h, z2.h
109; CHECK-NEXT:    fmov h1, #1.00000000
110; CHECK-NEXT:    mov z0.h, p0/m, h1
111; CHECK-NEXT:    ret
112  %b = insertelement <vscale x 8 x half> %a, half 1.0, i32 9
113  ret <vscale x 8 x half> %b
114}
115
116define <vscale x 16 x i8> @test_lane1_16xi8(<vscale x 16 x i8> %a) {
117; CHECK-LABEL: test_lane1_16xi8:
118; CHECK:       // %bb.0:
119; CHECK-NEXT:    mov w8, #1
120; CHECK-NEXT:    index z1.b, #0, #1
121; CHECK-NEXT:    ptrue p0.b
122; CHECK-NEXT:    mov z2.b, w8
123; CHECK-NEXT:    cmpeq p0.b, p0/z, z1.b, z2.b
124; CHECK-NEXT:    mov w8, #30
125; CHECK-NEXT:    mov z0.b, p0/m, w8
126; CHECK-NEXT:    ret
127  %b = insertelement <vscale x 16 x i8> %a, i8 30, i32 1
128  ret <vscale x 16 x i8> %b
129}
130
131define <vscale x 16 x i8> @test_lanex_16xi8(<vscale x 16 x i8> %a, i32 %x) {
132; CHECK-LABEL: test_lanex_16xi8:
133; CHECK:       // %bb.0:
134; CHECK-NEXT:    // kill: def $w0 killed $w0 def $x0
135; CHECK-NEXT:    sxtw x8, w0
136; CHECK-NEXT:    index z1.b, #0, #1
137; CHECK-NEXT:    ptrue p0.b
138; CHECK-NEXT:    mov z2.b, w8
139; CHECK-NEXT:    cmpeq p0.b, p0/z, z1.b, z2.b
140; CHECK-NEXT:    mov w8, #30
141; CHECK-NEXT:    mov z0.b, p0/m, w8
142; CHECK-NEXT:    ret
143  %b = insertelement <vscale x 16 x i8> %a, i8 30, i32 %x
144  ret <vscale x 16 x i8> %b
145}
146
147
148; Redundant lane insert
149define <vscale x 4 x i32> @extract_insert_4xi32(<vscale x 4 x i32> %a) {
150; CHECK-LABEL: extract_insert_4xi32:
151; CHECK:       // %bb.0:
152; CHECK-NEXT:    ret
153  %b = extractelement <vscale x 4 x i32> %a, i32 2
154  %c = insertelement <vscale x 4 x i32> %a, i32 %b, i32 2
155  ret <vscale x 4 x i32> %c
156}
157
158define <vscale x 8 x i16> @test_lane6_undef_8xi16(i16 %a) {
159; CHECK-LABEL: test_lane6_undef_8xi16:
160; CHECK:       // %bb.0:
161; CHECK-NEXT:    mov w8, #6
162; CHECK-NEXT:    index z0.h, #0, #1
163; CHECK-NEXT:    mov z1.h, w8
164; CHECK-NEXT:    ptrue p0.h
165; CHECK-NEXT:    cmpeq p0.h, p0/z, z0.h, z1.h
166; CHECK-NEXT:    mov z0.h, p0/m, w0
167; CHECK-NEXT:    ret
168  %b = insertelement <vscale x 8 x i16> undef, i16 %a, i32 6
169  ret <vscale x 8 x i16> %b
170}
171
172define <vscale x 16 x i8> @test_lane0_undef_16xi8(i8 %a) {
173; CHECK-LABEL: test_lane0_undef_16xi8:
174; CHECK:       // %bb.0:
175; CHECK-NEXT:    fmov s0, w0
176; CHECK-NEXT:    ret
177  %b = insertelement <vscale x 16 x i8> undef, i8 %a, i32 0
178  ret <vscale x 16 x i8> %b
179}
180
181define <vscale x 16 x i8> @test_insert0_of_extract0_16xi8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b) {
182; CHECK-LABEL: test_insert0_of_extract0_16xi8:
183; CHECK:       // %bb.0:
184; CHECK-NEXT:    mov z1.b, b1
185; CHECK-NEXT:    ptrue p0.b, vl1
186; CHECK-NEXT:    fmov w8, s1
187; CHECK-NEXT:    mov z0.b, p0/m, w8
188; CHECK-NEXT:    ret
189  %c = extractelement <vscale x 16 x i8> %b, i32 0
190  %d = insertelement <vscale x 16 x i8> %a, i8 %c, i32 0
191  ret <vscale x 16 x i8> %d
192}
193
194define <vscale x 16 x i8> @test_insert64_of_extract64_16xi8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b) {
195; CHECK-LABEL: test_insert64_of_extract64_16xi8:
196; CHECK:       // %bb.0:
197; CHECK-NEXT:    mov w8, #64
198; CHECK-NEXT:    index z2.b, #0, #1
199; CHECK-NEXT:    ptrue p0.b
200; CHECK-NEXT:    whilels p1.b, xzr, x8
201; CHECK-NEXT:    mov z3.b, w8
202; CHECK-NEXT:    lastb w8, p1, z1.b
203; CHECK-NEXT:    cmpeq p0.b, p0/z, z2.b, z3.b
204; CHECK-NEXT:    mov z0.b, p0/m, w8
205; CHECK-NEXT:    ret
206  %c = extractelement <vscale x 16 x i8> %b, i32 64
207  %d = insertelement <vscale x 16 x i8> %a, i8 %c, i32 64
208  ret <vscale x 16 x i8> %d
209}
210
211define <vscale x 16 x i8> @test_insert3_of_extract1_16xi8(<vscale x 16 x i8> %a, <vscale x 16 x i8> %b) {
212; CHECK-LABEL: test_insert3_of_extract1_16xi8:
213; CHECK:       // %bb.0:
214; CHECK-NEXT:    mov z1.b, z1.b[1]
215; CHECK-NEXT:    mov w8, #3
216; CHECK-NEXT:    index z2.b, #0, #1
217; CHECK-NEXT:    fmov w9, s1
218; CHECK-NEXT:    mov z1.b, w8
219; CHECK-NEXT:    ptrue p0.b
220; CHECK-NEXT:    cmpeq p0.b, p0/z, z2.b, z1.b
221; CHECK-NEXT:    mov z0.b, p0/m, w9
222; CHECK-NEXT:    ret
223  %c = extractelement <vscale x 16 x i8> %b, i32 1
224  %d = insertelement <vscale x 16 x i8> %a, i8 %c, i32 3
225  ret <vscale x 16 x i8> %d
226}
227