xref: /llvm-project/llvm/test/CodeGen/RISCV/rvv/splats-with-mixed-vl.ll (revision 92e0c0dc1a4f015e05a54094a4a94ddb0c5d9112)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -O3 -mtriple=riscv64 -mattr=+v < %s | FileCheck %s
3
4define void @constant_splat_fixed(ptr %p) {
5; CHECK-LABEL: constant_splat_fixed:
6; CHECK:       # %bb.0:
7; CHECK-NEXT:    vsetivli zero, 4, e32, m1, ta, ma
8; CHECK-NEXT:    vmv.v.i v8, 0
9; CHECK-NEXT:    vse32.v v8, (a0)
10; CHECK-NEXT:    ret
11  store <4 x i32> zeroinitializer, ptr %p
12  ret void
13}
14
15define void @constant_splat_scalable(ptr %p) {
16; CHECK-LABEL: constant_splat_scalable:
17; CHECK:       # %bb.0:
18; CHECK-NEXT:    vsetvli a1, zero, e32, mf2, ta, ma
19; CHECK-NEXT:    vmv.v.i v8, 0
20; CHECK-NEXT:    vse32.v v8, (a0)
21; CHECK-NEXT:    ret
22  store <vscale x 1 x i32> zeroinitializer, ptr %p
23  ret void
24}
25
26; FIXME: We should be able to use the earlier splat of zero here
27; since VLMAX >= 4.
28define void @constant_splat_scalable_then_fixed(ptr %p, ptr %p2) {
29; CHECK-LABEL: constant_splat_scalable_then_fixed:
30; CHECK:       # %bb.0:
31; CHECK-NEXT:    vsetvli a2, zero, e32, mf2, ta, ma
32; CHECK-NEXT:    vmv.v.i v8, 0
33; CHECK-NEXT:    vse32.v v8, (a0)
34; CHECK-NEXT:    vsetivli zero, 4, e32, m1, ta, ma
35; CHECK-NEXT:    vmv.v.i v8, 0
36; CHECK-NEXT:    vse32.v v8, (a1)
37; CHECK-NEXT:    ret
38  store <vscale x 1 x i32> zeroinitializer, ptr %p
39  store <4 x i32> zeroinitializer, ptr %p2
40  ret void
41}
42
43; We could widen the first splat to VLMAX, but this might not
44; be generally profitable.
45define void @constant_splat_fixed_then_scalable(ptr %p, ptr %p2) {
46; CHECK-LABEL: constant_splat_fixed_then_scalable:
47; CHECK:       # %bb.0:
48; CHECK-NEXT:    vsetivli zero, 4, e32, m1, ta, ma
49; CHECK-NEXT:    vmv.v.i v8, 0
50; CHECK-NEXT:    vse32.v v8, (a1)
51; CHECK-NEXT:    vsetvli a1, zero, e32, mf2, ta, ma
52; CHECK-NEXT:    vmv.v.i v8, 0
53; CHECK-NEXT:    vse32.v v8, (a0)
54; CHECK-NEXT:    ret
55  store <4 x i32> zeroinitializer, ptr %p2
56  store <vscale x 1 x i32> zeroinitializer, ptr %p
57  ret void
58}
59
60define void @splat_scalable(ptr %p, i32 %v) {
61; CHECK-LABEL: splat_scalable:
62; CHECK:       # %bb.0:
63; CHECK-NEXT:    vsetvli a2, zero, e32, mf2, ta, ma
64; CHECK-NEXT:    vmv.v.x v8, a1
65; CHECK-NEXT:    vse32.v v8, (a0)
66; CHECK-NEXT:    ret
67  %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0
68  %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer
69  store <vscale x 1 x i32> %splat, ptr %p
70  ret void
71}
72
73define void @splat_fixed(ptr %p, i32 %v) {
74; CHECK-LABEL: splat_fixed:
75; CHECK:       # %bb.0:
76; CHECK-NEXT:    vsetivli zero, 4, e32, m1, ta, ma
77; CHECK-NEXT:    vmv.v.x v8, a1
78; CHECK-NEXT:    vse32.v v8, (a0)
79; CHECK-NEXT:    ret
80  %elt.head = insertelement <4 x i32> poison, i32 %v, i32 0
81  %splat = shufflevector <4 x i32> %elt.head, <4 x i32> poison, <4 x i32> zeroinitializer
82  store <4 x i32> %splat, ptr %p
83  ret void
84}
85
86; FIXME: We should reschedule the first splat to reduce the need
87; for toggling VL
88define void @mixed_splats1(ptr %p, i32 %v) {
89; CHECK-LABEL: mixed_splats1:
90; CHECK:       # %bb.0:
91; CHECK-NEXT:    vsetvli a2, zero, e32, mf2, ta, ma
92; CHECK-NEXT:    vmv.v.x v8, a1
93; CHECK-NEXT:    vsetivli zero, 4, e32, m1, ta, ma
94; CHECK-NEXT:    vmv.v.i v9, 0
95; CHECK-NEXT:    vse32.v v9, (a0)
96; CHECK-NEXT:    vsetvli a1, zero, e32, mf2, ta, ma
97; CHECK-NEXT:    vse32.v v8, (a0)
98; CHECK-NEXT:    ret
99  %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0
100  %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer
101
102  store <4 x i32> zeroinitializer, ptr %p
103  store <vscale x 1 x i32> %splat, ptr %p
104  ret void
105}
106
107define void @mixed_splats2(ptr %p, i32 %v) {
108; CHECK-LABEL: mixed_splats2:
109; CHECK:       # %bb.0:
110; CHECK-NEXT:    vsetvli a2, zero, e32, mf2, ta, ma
111; CHECK-NEXT:    vmv.v.x v8, a1
112; CHECK-NEXT:    vse32.v v8, (a0)
113; CHECK-NEXT:    vsetivli zero, 4, e32, m1, ta, ma
114; CHECK-NEXT:    vmv.v.i v8, 0
115; CHECK-NEXT:    vse32.v v8, (a0)
116; CHECK-NEXT:    ret
117  %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0
118  %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer
119
120  store <vscale x 1 x i32> %splat, ptr %p
121  store <4 x i32> zeroinitializer, ptr %p
122  ret void
123}
124
125define void @extract_vector(ptr %p, i32 %v) {
126; CHECK-LABEL: extract_vector:
127; CHECK:       # %bb.0:
128; CHECK-NEXT:    vsetivli zero, 4, e32, m1, ta, ma
129; CHECK-NEXT:    vmv.v.x v8, a1
130; CHECK-NEXT:    vse32.v v8, (a0)
131; CHECK-NEXT:    ret
132  %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0
133  %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer
134
135  %fv = call <4 x i32> @llvm.vector.extract.v4i32.nxv1132(<vscale x 1 x i32> %splat, i64 0)
136  store <4 x i32> %fv, ptr %p
137  ret void
138}
139
140define void @extract_vector_multiuse1(ptr %p, ptr %p2, i32 %v) {
141; CHECK-LABEL: extract_vector_multiuse1:
142; CHECK:       # %bb.0:
143; CHECK-NEXT:    vsetivli zero, 4, e32, m1, ta, ma
144; CHECK-NEXT:    vmv.v.x v8, a2
145; CHECK-NEXT:    vse32.v v8, (a0)
146; CHECK-NEXT:    vse32.v v8, (a1)
147; CHECK-NEXT:    ret
148  %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0
149  %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer
150
151  %fv = call <4 x i32> @llvm.vector.extract.v4i32.nxv1132(<vscale x 1 x i32> %splat, i64 0)
152  store <4 x i32> %fv, ptr %p
153  store <4 x i32> %fv, ptr %p2
154  ret void
155}
156
157define <vscale x 1 x i32> @extract_vector_multiuse2(ptr %p, ptr %p2, i32 %v) {
158; CHECK-LABEL: extract_vector_multiuse2:
159; CHECK:       # %bb.0:
160; CHECK-NEXT:    vsetvli a1, zero, e32, mf2, ta, ma
161; CHECK-NEXT:    vmv.v.x v8, a2
162; CHECK-NEXT:    vsetivli zero, 4, e32, m1, ta, ma
163; CHECK-NEXT:    vse32.v v8, (a0)
164; CHECK-NEXT:    ret
165  %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0
166  %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer
167
168  %fv = call <4 x i32> @llvm.vector.extract.v4i32.nxv1132(<vscale x 1 x i32> %splat, i64 0)
169  store <4 x i32> %fv, ptr %p
170  ret <vscale x 1 x i32> %splat
171}
172
173define void @extract_vector_mixed1(ptr %p, ptr %p2, i32 %v) {
174; CHECK-LABEL: extract_vector_mixed1:
175; CHECK:       # %bb.0:
176; CHECK-NEXT:    vsetvli a3, zero, e32, mf2, ta, ma
177; CHECK-NEXT:    vmv.v.x v8, a2
178; CHECK-NEXT:    vsetivli zero, 4, e32, m1, ta, ma
179; CHECK-NEXT:    vse32.v v8, (a0)
180; CHECK-NEXT:    vsetvli a0, zero, e32, mf2, ta, ma
181; CHECK-NEXT:    vse32.v v8, (a1)
182; CHECK-NEXT:    ret
183  %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0
184  %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer
185
186  %fv = call <4 x i32> @llvm.vector.extract.v4i32.nxv1132(<vscale x 1 x i32> %splat, i64 0)
187
188  store <4 x i32> %fv, ptr %p
189  store <vscale x 1 x i32> %splat, ptr %p2
190  ret void
191}
192
193define void @extract_vector_mixed2(ptr %p, ptr %p2, i32 %v) {
194; CHECK-LABEL: extract_vector_mixed2:
195; CHECK:       # %bb.0:
196; CHECK-NEXT:    vsetvli a3, zero, e32, mf2, ta, ma
197; CHECK-NEXT:    vmv.v.x v8, a2
198; CHECK-NEXT:    vse32.v v8, (a0)
199; CHECK-NEXT:    vsetivli zero, 4, e32, m1, ta, ma
200; CHECK-NEXT:    vse32.v v8, (a1)
201; CHECK-NEXT:    ret
202  %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0
203  %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer
204  store <vscale x 1 x i32> %splat, ptr %p
205
206  %fv = call <4 x i32> @llvm.vector.extract.v4i32.nxv1132(<vscale x 1 x i32> %splat, i64 0)
207  store <4 x i32> %fv, ptr %p2
208  ret void
209}
210
211define void @extract_vector_mixed3(ptr %p, ptr %p2, i32 %v) {
212; CHECK-LABEL: extract_vector_mixed3:
213; CHECK:       # %bb.0:
214; CHECK-NEXT:    vsetvli a3, zero, e32, mf2, ta, ma
215; CHECK-NEXT:    vmv.v.x v8, a2
216; CHECK-NEXT:    vse32.v v8, (a0)
217; CHECK-NEXT:    vsetivli zero, 4, e32, m1, ta, ma
218; CHECK-NEXT:    vse32.v v8, (a1)
219; CHECK-NEXT:    ret
220  %elt.head = insertelement <vscale x 1 x i32> poison, i32 %v, i32 0
221  %splat = shufflevector <vscale x 1 x i32> %elt.head, <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer
222  %fv = call <4 x i32> @llvm.vector.extract.v4i32.nxv1132(<vscale x 1 x i32> %splat, i64 0)
223
224  store <vscale x 1 x i32> %splat, ptr %p
225  store <4 x i32> %fv, ptr %p2
226  ret void
227}
228
229
230declare <4 x i32> @llvm.vector.extract.v4i32.nxv1132(<vscale x 1 x i32> %vec, i64 %idx)
231