1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -target-abi=ilp32d -mattr=+experimental-v,+experimental-zfh,+f,+d -verify-machineinstrs -riscv-v-vector-bits-min=128 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV32
3; RUN: llc -mtriple=riscv64 -target-abi=lp64d -mattr=+experimental-v,+experimental-zfh,+f,+d -verify-machineinstrs -riscv-v-vector-bits-min=128 -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK,RV64
4
5; FIXME: This codegen needs to be improved. These tests previously asserted
6; type legalizing the i64 type on RV32.
7
8define void @insertelt_v4i64(<4 x i64>* %x, i64 %y) {
9; RV32-LABEL: insertelt_v4i64:
10; RV32:       # %bb.0:
11; RV32-NEXT:    vsetivli a3, 4, e64,m2,ta,mu
12; RV32-NEXT:    vle64.v v26, (a0)
13; RV32-NEXT:    vsetivli a3, 2, e32,m2,ta,mu
14; RV32-NEXT:    vmv.v.i v28, 0
15; RV32-NEXT:    vslide1up.vx v30, v28, a2
16; RV32-NEXT:    vslide1up.vx v28, v30, a1
17; RV32-NEXT:    vsetivli a1, 4, e64,m2,tu,mu
18; RV32-NEXT:    vslideup.vi v26, v28, 3
19; RV32-NEXT:    vsetivli a1, 4, e64,m2,ta,mu
20; RV32-NEXT:    vse64.v v26, (a0)
21; RV32-NEXT:    ret
22;
23; RV64-LABEL: insertelt_v4i64:
24; RV64:       # %bb.0:
25; RV64-NEXT:    vsetivli a2, 4, e64,m2,ta,mu
26; RV64-NEXT:    vle64.v v26, (a0)
27; RV64-NEXT:    vmv.s.x v28, a1
28; RV64-NEXT:    vsetivli a1, 4, e64,m2,tu,mu
29; RV64-NEXT:    vslideup.vi v26, v28, 3
30; RV64-NEXT:    vsetivli a1, 4, e64,m2,ta,mu
31; RV64-NEXT:    vse64.v v26, (a0)
32; RV64-NEXT:    ret
33  %a = load <4 x i64>, <4 x i64>* %x
34  %b = insertelement <4 x i64> %a, i64 %y, i32 3
35  store <4 x i64> %b, <4 x i64>* %x
36  ret void
37}
38
39; This uses a non-power of 2 type so that it isn't an MVT.
40; The align keeps the type legalizer from using a 256 bit load so we must split
41; it. This some operations that weren't support for scalable vectors when
42; this test was written.
43define void @insertelt_v3i64(<3 x i64>* %x, i64 %y) {
44; RV32-LABEL: insertelt_v3i64:
45; RV32:       # %bb.0:
46; RV32-NEXT:    vsetivli a3, 2, e64,m1,ta,mu
47; RV32-NEXT:    vle64.v v26, (a0)
48; RV32-NEXT:    vsetivli a3, 8, e32,m2,ta,mu
49; RV32-NEXT:    vmv.v.i v28, 0
50; RV32-NEXT:    vsetivli a3, 2, e64,m2,tu,mu
51; RV32-NEXT:    vslideup.vi v28, v26, 0
52; RV32-NEXT:    lw a3, 16(a0)
53; RV32-NEXT:    addi a4, a0, 20
54; RV32-NEXT:    vsetivli a5, 4, e32,m1,ta,mu
55; RV32-NEXT:    vlse32.v v26, (a4), zero
56; RV32-NEXT:    vmv.s.x v26, a3
57; RV32-NEXT:    vsetivli a3, 4, e64,m2,tu,mu
58; RV32-NEXT:    vslideup.vi v28, v26, 2
59; RV32-NEXT:    vsetivli a3, 2, e32,m2,ta,mu
60; RV32-NEXT:    vmv.v.i v26, 0
61; RV32-NEXT:    vslide1up.vx v30, v26, a2
62; RV32-NEXT:    vslide1up.vx v26, v30, a1
63; RV32-NEXT:    vsetivli a3, 3, e64,m2,tu,mu
64; RV32-NEXT:    vslideup.vi v28, v26, 2
65; RV32-NEXT:    sw a1, 16(a0)
66; RV32-NEXT:    sw a2, 20(a0)
67; RV32-NEXT:    vsetivli a1, 2, e64,m1,ta,mu
68; RV32-NEXT:    vse64.v v28, (a0)
69; RV32-NEXT:    ret
70;
71; RV64-LABEL: insertelt_v3i64:
72; RV64:       # %bb.0:
73; RV64-NEXT:    sd a1, 16(a0)
74; RV64-NEXT:    ret
75  %a = load <3 x i64>, <3 x i64>* %x, align 8
76  %b = insertelement <3 x i64> %a, i64 %y, i32 2
77  store <3 x i64> %b, <3 x i64>* %x
78  ret void
79}
80
81define void @insertelt_v16i8(<16 x i8>* %x, i8 %y) {
82; CHECK-LABEL: insertelt_v16i8:
83; CHECK:       # %bb.0:
84; CHECK-NEXT:    vsetivli a2, 16, e8,m1,ta,mu
85; CHECK-NEXT:    vle8.v v25, (a0)
86; CHECK-NEXT:    vmv.s.x v26, a1
87; CHECK-NEXT:    vsetivli a1, 15, e8,m1,tu,mu
88; CHECK-NEXT:    vslideup.vi v25, v26, 14
89; CHECK-NEXT:    vsetivli a1, 16, e8,m1,ta,mu
90; CHECK-NEXT:    vse8.v v25, (a0)
91; CHECK-NEXT:    ret
92  %a = load <16 x i8>, <16 x i8>* %x
93  %b = insertelement <16 x i8> %a, i8 %y, i32 14
94  store <16 x i8> %b, <16 x i8>* %x
95  ret void
96}
97
98define void @insertelt_v32i16(<32 x i16>* %x, i16 %y, i32 %idx) {
99; RV32-LABEL: insertelt_v32i16:
100; RV32:       # %bb.0:
101; RV32-NEXT:    addi a3, zero, 32
102; RV32-NEXT:    vsetvli a4, a3, e16,m4,ta,mu
103; RV32-NEXT:    vle16.v v28, (a0)
104; RV32-NEXT:    vmv.s.x v8, a1
105; RV32-NEXT:    addi a1, a2, 1
106; RV32-NEXT:    vsetvli a1, a1, e16,m4,tu,mu
107; RV32-NEXT:    vslideup.vx v28, v8, a2
108; RV32-NEXT:    vsetvli a1, a3, e16,m4,ta,mu
109; RV32-NEXT:    vse16.v v28, (a0)
110; RV32-NEXT:    ret
111;
112; RV64-LABEL: insertelt_v32i16:
113; RV64:       # %bb.0:
114; RV64-NEXT:    addi a3, zero, 32
115; RV64-NEXT:    vsetvli a4, a3, e16,m4,ta,mu
116; RV64-NEXT:    vle16.v v28, (a0)
117; RV64-NEXT:    vmv.s.x v8, a1
118; RV64-NEXT:    sext.w a1, a2
119; RV64-NEXT:    addi a2, a1, 1
120; RV64-NEXT:    vsetvli a2, a2, e16,m4,tu,mu
121; RV64-NEXT:    vslideup.vx v28, v8, a1
122; RV64-NEXT:    vsetvli a1, a3, e16,m4,ta,mu
123; RV64-NEXT:    vse16.v v28, (a0)
124; RV64-NEXT:    ret
125  %a = load <32 x i16>, <32 x i16>* %x
126  %b = insertelement <32 x i16> %a, i16 %y, i32 %idx
127  store <32 x i16> %b, <32 x i16>* %x
128  ret void
129}
130
131define void @insertelt_v8f32(<8 x float>* %x, float %y, i32 %idx) {
132; RV32-LABEL: insertelt_v8f32:
133; RV32:       # %bb.0:
134; RV32-NEXT:    vsetivli a2, 8, e32,m2,ta,mu
135; RV32-NEXT:    vle32.v v26, (a0)
136; RV32-NEXT:    vfmv.s.f v28, fa0
137; RV32-NEXT:    addi a2, a1, 1
138; RV32-NEXT:    vsetvli a2, a2, e32,m2,tu,mu
139; RV32-NEXT:    vslideup.vx v26, v28, a1
140; RV32-NEXT:    vsetivli a1, 8, e32,m2,ta,mu
141; RV32-NEXT:    vse32.v v26, (a0)
142; RV32-NEXT:    ret
143;
144; RV64-LABEL: insertelt_v8f32:
145; RV64:       # %bb.0:
146; RV64-NEXT:    vsetivli a2, 8, e32,m2,ta,mu
147; RV64-NEXT:    vle32.v v26, (a0)
148; RV64-NEXT:    vfmv.s.f v28, fa0
149; RV64-NEXT:    sext.w a1, a1
150; RV64-NEXT:    addi a2, a1, 1
151; RV64-NEXT:    vsetvli a2, a2, e32,m2,tu,mu
152; RV64-NEXT:    vslideup.vx v26, v28, a1
153; RV64-NEXT:    vsetivli a1, 8, e32,m2,ta,mu
154; RV64-NEXT:    vse32.v v26, (a0)
155; RV64-NEXT:    ret
156  %a = load <8 x float>, <8 x float>* %x
157  %b = insertelement <8 x float> %a, float %y, i32 %idx
158  store <8 x float> %b, <8 x float>* %x
159  ret void
160}
161
162define void @insertelt_v8i64_0(<8 x i64>* %x) {
163; CHECK-LABEL: insertelt_v8i64_0:
164; CHECK:       # %bb.0:
165; CHECK-NEXT:    vsetivli a1, 8, e64,m4,ta,mu
166; CHECK-NEXT:    vle64.v v28, (a0)
167; CHECK-NEXT:    addi a1, zero, -1
168; CHECK-NEXT:    vmv.s.x v28, a1
169; CHECK-NEXT:    vse64.v v28, (a0)
170; CHECK-NEXT:    ret
171  %a = load <8 x i64>, <8 x i64>* %x
172  %b = insertelement <8 x i64> %a, i64 -1, i32 0
173  store <8 x i64> %b, <8 x i64>* %x
174  ret void
175}
176
177define void @insertelt_v8i64(<8 x i64>* %x, i32 %idx) {
178; RV32-LABEL: insertelt_v8i64:
179; RV32:       # %bb.0:
180; RV32-NEXT:    vsetivli a2, 8, e64,m4,ta,mu
181; RV32-NEXT:    vle64.v v28, (a0)
182; RV32-NEXT:    addi a2, zero, -1
183; RV32-NEXT:    vmv.s.x v8, a2
184; RV32-NEXT:    addi a2, a1, 1
185; RV32-NEXT:    vsetvli a2, a2, e64,m4,tu,mu
186; RV32-NEXT:    vslideup.vx v28, v8, a1
187; RV32-NEXT:    vsetivli a1, 8, e64,m4,ta,mu
188; RV32-NEXT:    vse64.v v28, (a0)
189; RV32-NEXT:    ret
190;
191; RV64-LABEL: insertelt_v8i64:
192; RV64:       # %bb.0:
193; RV64-NEXT:    vsetivli a2, 8, e64,m4,ta,mu
194; RV64-NEXT:    vle64.v v28, (a0)
195; RV64-NEXT:    addi a2, zero, -1
196; RV64-NEXT:    vmv.s.x v8, a2
197; RV64-NEXT:    sext.w a1, a1
198; RV64-NEXT:    addi a2, a1, 1
199; RV64-NEXT:    vsetvli a2, a2, e64,m4,tu,mu
200; RV64-NEXT:    vslideup.vx v28, v8, a1
201; RV64-NEXT:    vsetivli a1, 8, e64,m4,ta,mu
202; RV64-NEXT:    vse64.v v28, (a0)
203; RV64-NEXT:    ret
204  %a = load <8 x i64>, <8 x i64>* %x
205  %b = insertelement <8 x i64> %a, i64 -1, i32 %idx
206  store <8 x i64> %b, <8 x i64>* %x
207  ret void
208}
209
210define void @insertelt_c6_v8i64_0(<8 x i64>* %x) {
211; CHECK-LABEL: insertelt_c6_v8i64_0:
212; CHECK:       # %bb.0:
213; CHECK-NEXT:    vsetivli a1, 8, e64,m4,ta,mu
214; CHECK-NEXT:    vle64.v v28, (a0)
215; CHECK-NEXT:    addi a1, zero, 6
216; CHECK-NEXT:    vmv.s.x v28, a1
217; CHECK-NEXT:    vse64.v v28, (a0)
218; CHECK-NEXT:    ret
219  %a = load <8 x i64>, <8 x i64>* %x
220  %b = insertelement <8 x i64> %a, i64 6, i32 0
221  store <8 x i64> %b, <8 x i64>* %x
222  ret void
223}
224
225define void @insertelt_c6_v8i64(<8 x i64>* %x, i32 %idx) {
226; RV32-LABEL: insertelt_c6_v8i64:
227; RV32:       # %bb.0:
228; RV32-NEXT:    vsetivli a2, 8, e64,m4,ta,mu
229; RV32-NEXT:    vle64.v v28, (a0)
230; RV32-NEXT:    addi a2, zero, 6
231; RV32-NEXT:    vmv.s.x v8, a2
232; RV32-NEXT:    addi a2, a1, 1
233; RV32-NEXT:    vsetvli a2, a2, e64,m4,tu,mu
234; RV32-NEXT:    vslideup.vx v28, v8, a1
235; RV32-NEXT:    vsetivli a1, 8, e64,m4,ta,mu
236; RV32-NEXT:    vse64.v v28, (a0)
237; RV32-NEXT:    ret
238;
239; RV64-LABEL: insertelt_c6_v8i64:
240; RV64:       # %bb.0:
241; RV64-NEXT:    vsetivli a2, 8, e64,m4,ta,mu
242; RV64-NEXT:    vle64.v v28, (a0)
243; RV64-NEXT:    addi a2, zero, 6
244; RV64-NEXT:    vmv.s.x v8, a2
245; RV64-NEXT:    sext.w a1, a1
246; RV64-NEXT:    addi a2, a1, 1
247; RV64-NEXT:    vsetvli a2, a2, e64,m4,tu,mu
248; RV64-NEXT:    vslideup.vx v28, v8, a1
249; RV64-NEXT:    vsetivli a1, 8, e64,m4,ta,mu
250; RV64-NEXT:    vse64.v v28, (a0)
251; RV64-NEXT:    ret
252  %a = load <8 x i64>, <8 x i64>* %x
253  %b = insertelement <8 x i64> %a, i64 6, i32 %idx
254  store <8 x i64> %b, <8 x i64>* %x
255  ret void
256}
257
258; Test that using a insertelement at element 0 by a later operation doesn't
259; crash the compiler.
260define void @insertelt_c6_v8i64_0_add(<8 x i64>* %x, <8 x i64>* %y) {
261; CHECK-LABEL: insertelt_c6_v8i64_0_add:
262; CHECK:       # %bb.0:
263; CHECK-NEXT:    vsetivli a2, 8, e64,m4,ta,mu
264; CHECK-NEXT:    vle64.v v28, (a0)
265; CHECK-NEXT:    vle64.v v8, (a1)
266; CHECK-NEXT:    addi a1, zero, 6
267; CHECK-NEXT:    vmv.s.x v28, a1
268; CHECK-NEXT:    vadd.vv v28, v28, v8
269; CHECK-NEXT:    vse64.v v28, (a0)
270; CHECK-NEXT:    ret
271  %a = load <8 x i64>, <8 x i64>* %x
272  %b = insertelement <8 x i64> %a, i64 6, i32 0
273  %c = load <8 x i64>, <8 x i64>* %y
274  %d = add <8 x i64> %b, %c
275  store <8 x i64> %d, <8 x i64>* %x
276  ret void
277}
278