Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / RISCV / rvv / vsetvli-insert.ll
blob4d0f640408dd2a91183e5882da348b8e168fe312
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv64 -mattr=+m,+f,+d,+a,+c,+v \
3 ; RUN:   -target-abi=lp64d -verify-machineinstrs -O2 < %s | FileCheck %s
5 declare i64 @llvm.riscv.vsetvli(i64, i64, i64)
6 declare i64 @llvm.riscv.vsetvlimax(i64, i64)
7 declare <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(
8   <vscale x 1 x double>,
9   <vscale x 1 x double>,
10   <vscale x 1 x double>,
11   i64, i64)
12 declare <vscale x 1 x i64> @llvm.riscv.vle.mask.nxv1i64(
13   <vscale x 1 x i64>,
14   <vscale x 1 x i64>*,
15   <vscale x 1 x i1>,
16   i64, i64)
18 define <vscale x 1 x double> @test1(i64 %avl, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {
19 ; CHECK-LABEL: test1:
20 ; CHECK:       # %bb.0: # %entry
21 ; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma
22 ; CHECK-NEXT:    vfadd.vv v8, v8, v9
23 ; CHECK-NEXT:    ret
24 entry:
25   %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 2, i64 7)
26   %1 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(
27     <vscale x 1 x double> undef,
28     <vscale x 1 x double> %a,
29     <vscale x 1 x double> %b,
30     i64 7, i64 %0)
31   ret <vscale x 1 x double> %1
34 define <vscale x 1 x double> @test2(i64 %avl, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {
35 ; CHECK-LABEL: test2:
36 ; CHECK:       # %bb.0: # %entry
37 ; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma
38 ; CHECK-NEXT:    vfadd.vv v8, v8, v9
39 ; CHECK-NEXT:    ret
40 entry:
41   %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 2, i64 7)
42   %1 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(
43     <vscale x 1 x double> undef,
44     <vscale x 1 x double> %a,
45     <vscale x 1 x double> %b,
46     i64 7, i64 %avl)
47   ret <vscale x 1 x double> %1
50 define <vscale x 1 x i64> @test3(i64 %avl, <vscale x 1 x i64> %a, <vscale x 1 x i64>* %b, <vscale x 1 x i1> %c) nounwind {
51 ; CHECK-LABEL: test3:
52 ; CHECK:       # %bb.0: # %entry
53 ; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, mu
54 ; CHECK-NEXT:    vle64.v v8, (a1), v0.t
55 ; CHECK-NEXT:    ret
56 entry:
57   %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 0)
58   %1 = call <vscale x 1 x i64> @llvm.riscv.vle.mask.nxv1i64(
59     <vscale x 1 x i64> %a,
60     <vscale x 1 x i64>* %b,
61     <vscale x 1 x i1> %c,
62     i64 %0, i64 1)
64   ret <vscale x 1 x i64> %1
67 define <vscale x 1 x i64> @test4(i64 %avl, <vscale x 1 x i64> %a, <vscale x 1 x i64>* %b, <vscale x 1 x i1> %c) nounwind {
68 ; CHECK-LABEL: test4:
69 ; CHECK:       # %bb.0: # %entry
70 ; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, mu
71 ; CHECK-NEXT:    vle64.v v8, (a1), v0.t
72 ; CHECK-NEXT:    ret
73 entry:
74   %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 0)
75   %1 = call <vscale x 1 x i64> @llvm.riscv.vle.mask.nxv1i64(
76     <vscale x 1 x i64> %a,
77     <vscale x 1 x i64>* %b,
78     <vscale x 1 x i1> %c,
79     i64 %avl, i64 1)
81   ret <vscale x 1 x i64> %1
84 ; Make sure we don't insert a vsetvli for the vmand instruction.
85 define <vscale x 1 x i1> @test5(<vscale x 1 x i64> %0, <vscale x 1 x i64> %1, <vscale x 1 x i1> %2, i64 %avl) nounwind {
86 ; CHECK-LABEL: test5:
87 ; CHECK:       # %bb.0: # %entry
88 ; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma
89 ; CHECK-NEXT:    vmseq.vv v8, v8, v9
90 ; CHECK-NEXT:    vmand.mm v0, v8, v0
91 ; CHECK-NEXT:    ret
92 entry:
93   %vl = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 0)
94   %a = call <vscale x 1 x i1> @llvm.riscv.vmseq.nxv1i64.i64(<vscale x 1 x i64> %0, <vscale x 1 x i64> %1, i64 %vl)
95   %b = call <vscale x 1 x i1> @llvm.riscv.vmand.nxv1i1.i64(<vscale x 1 x i1> %a, <vscale x 1 x i1> %2, i64 %vl)
96   ret <vscale x 1 x i1> %b
98 declare <vscale x 1 x i1> @llvm.riscv.vmseq.nxv1i64.i64(<vscale x 1 x i64>, <vscale x 1 x i64>, i64)
99 declare <vscale x 1 x i1> @llvm.riscv.vmand.nxv1i1.i64(<vscale x 1 x i1>, <vscale x 1 x i1>, i64)
101 ; Make sure we don't insert a vsetvli for the vmor instruction.
102 define void @test6(i32* nocapture readonly %A, i32* nocapture %B, i64 %n) {
103 ; CHECK-LABEL: test6:
104 ; CHECK:       # %bb.0: # %entry
105 ; CHECK-NEXT:    vsetvli a6, a2, e32, m1, ta, ma
106 ; CHECK-NEXT:    beqz a6, .LBB5_3
107 ; CHECK-NEXT:  # %bb.1: # %for.body.preheader
108 ; CHECK-NEXT:    li a4, 0
109 ; CHECK-NEXT:  .LBB5_2: # %for.body
110 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
111 ; CHECK-NEXT:    slli a3, a4, 2
112 ; CHECK-NEXT:    add a5, a0, a3
113 ; CHECK-NEXT:    vle32.v v8, (a5)
114 ; CHECK-NEXT:    vmsle.vi v9, v8, -3
115 ; CHECK-NEXT:    vmsgt.vi v10, v8, 2
116 ; CHECK-NEXT:    vmor.mm v0, v9, v10
117 ; CHECK-NEXT:    add a3, a3, a1
118 ; CHECK-NEXT:    vse32.v v8, (a3), v0.t
119 ; CHECK-NEXT:    add a4, a4, a6
120 ; CHECK-NEXT:    vsetvli a6, a2, e32, m1, ta, ma
121 ; CHECK-NEXT:    bnez a6, .LBB5_2
122 ; CHECK-NEXT:  .LBB5_3: # %for.cond.cleanup
123 ; CHECK-NEXT:    ret
124 entry:
125   %0 = tail call i64 @llvm.riscv.vsetvli.i64(i64 %n, i64 2, i64 0)
126   %cmp.not11 = icmp eq i64 %0, 0
127   br i1 %cmp.not11, label %for.cond.cleanup, label %for.body
129 for.cond.cleanup:                                 ; preds = %for.body, %entry
130   ret void
132 for.body:                                         ; preds = %entry, %for.body
133   %1 = phi i64 [ %8, %for.body ], [ %0, %entry ]
134   %i.012 = phi i64 [ %add, %for.body ], [ 0, %entry ]
135   %add.ptr = getelementptr inbounds i32, i32* %A, i64 %i.012
136   %2 = bitcast i32* %add.ptr to <vscale x 2 x i32>*
137   %3 = tail call <vscale x 2 x i32> @llvm.riscv.vle.nxv2i32.i64(<vscale x 2 x i32> undef, <vscale x 2 x i32>* %2, i64 %1)
138   %4 = tail call <vscale x 2 x i1> @llvm.riscv.vmslt.nxv2i32.i32.i64(<vscale x 2 x i32> %3, i32 -2, i64 %1)
139   %5 = tail call <vscale x 2 x i1> @llvm.riscv.vmsgt.nxv2i32.i32.i64(<vscale x 2 x i32> %3, i32 2, i64 %1)
140   %6 = tail call <vscale x 2 x i1> @llvm.riscv.vmor.nxv2i1.i64(<vscale x 2 x i1> %4, <vscale x 2 x i1> %5, i64 %1)
141   %add.ptr1 = getelementptr inbounds i32, i32* %B, i64 %i.012
142   %7 = bitcast i32* %add.ptr1 to <vscale x 2 x i32>*
143   tail call void @llvm.riscv.vse.mask.nxv2i32.i64(<vscale x 2 x i32> %3, <vscale x 2 x i32>* %7, <vscale x 2 x i1> %6, i64 %1)
144   %add = add i64 %1, %i.012
145   %8 = tail call i64 @llvm.riscv.vsetvli.i64(i64 %n, i64 2, i64 0)
146   %cmp.not = icmp eq i64 %8, 0
147   br i1 %cmp.not, label %for.cond.cleanup, label %for.body
150 define <vscale x 1 x i64> @test7(<vscale x 1 x i64> %a, i64 %b, <vscale x 1 x i1> %mask) nounwind {
151 ; CHECK-LABEL: test7:
152 ; CHECK:       # %bb.0: # %entry
153 ; CHECK-NEXT:    vsetivli zero, 1, e64, m1, tu, ma
154 ; CHECK-NEXT:    vmv.s.x v8, a0
155 ; CHECK-NEXT:    ret
156 entry:
157   %x = tail call i64 @llvm.riscv.vsetvlimax(i64 3, i64 0)
158   %y = call <vscale x 1 x i64> @llvm.riscv.vmv.s.x.nxv1i64(
159     <vscale x 1 x i64> %a,
160     i64 %b, i64 1)
162   ret <vscale x 1 x i64> %y
165 define <vscale x 1 x i64> @test8(<vscale x 1 x i64> %a, i64 %b, <vscale x 1 x i1> %mask) nounwind {
166 ; CHECK-LABEL: test8:
167 ; CHECK:       # %bb.0: # %entry
168 ; CHECK-NEXT:    vsetivli zero, 2, e64, m1, tu, ma
169 ; CHECK-NEXT:    vmv.s.x v8, a0
170 ; CHECK-NEXT:    ret
171 entry:
172   %x = tail call i64 @llvm.riscv.vsetvli(i64 6, i64 3, i64 0)
173   %y = call <vscale x 1 x i64> @llvm.riscv.vmv.s.x.nxv1i64(<vscale x 1 x i64> %a, i64 %b, i64 2)
174   ret <vscale x 1 x i64> %y
177 define <vscale x 1 x i64> @test9(<vscale x 1 x i64> %a, i64 %b, <vscale x 1 x i1> %mask) nounwind {
178 ; CHECK-LABEL: test9:
179 ; CHECK:       # %bb.0: # %entry
180 ; CHECK-NEXT:    vsetivli zero, 9, e64, m1, tu, mu
181 ; CHECK-NEXT:    vadd.vv v8, v8, v8, v0.t
182 ; CHECK-NEXT:    vmv.s.x v8, a0
183 ; CHECK-NEXT:    ret
184 entry:
185   %x = call <vscale x 1 x i64> @llvm.riscv.vadd.mask.nxv1i64.nxv1i64(
186     <vscale x 1 x i64> %a,
187     <vscale x 1 x i64> %a,
188     <vscale x 1 x i64> %a,
189     <vscale x 1 x i1> %mask,
190     i64 9,
191     i64 0)
192   %y = call <vscale x 1 x i64> @llvm.riscv.vmv.s.x.nxv1i64(<vscale x 1 x i64> %x, i64 %b, i64 2)
193   ret <vscale x 1 x i64> %y
196 define <vscale x 1 x double> @test10(<vscale x 1 x double> %a, double %b) nounwind {
197 ; CHECK-LABEL: test10:
198 ; CHECK:       # %bb.0: # %entry
199 ; CHECK-NEXT:    vsetivli zero, 1, e64, m1, tu, ma
200 ; CHECK-NEXT:    vfmv.s.f v8, fa0
201 ; CHECK-NEXT:    ret
202 entry:
203   %x = tail call i64 @llvm.riscv.vsetvlimax(i64 3, i64 0)
204   %y = call <vscale x 1 x double> @llvm.riscv.vfmv.s.f.nxv1f64(
205     <vscale x 1 x double> %a, double %b, i64 1)
206   ret <vscale x 1 x double> %y
209 define <vscale x 1 x double> @test11(<vscale x 1 x double> %a, double %b) nounwind {
210 ; CHECK-LABEL: test11:
211 ; CHECK:       # %bb.0: # %entry
212 ; CHECK-NEXT:    vsetivli zero, 2, e64, m1, tu, ma
213 ; CHECK-NEXT:    vfmv.s.f v8, fa0
214 ; CHECK-NEXT:    ret
215 entry:
216   %x = tail call i64 @llvm.riscv.vsetvli(i64 6, i64 3, i64 0)
217   %y = call <vscale x 1 x double> @llvm.riscv.vfmv.s.f.nxv1f64(
218     <vscale x 1 x double> %a, double %b, i64 2)
219   ret <vscale x 1 x double> %y
222 define <vscale x 1 x double> @test12(<vscale x 1 x double> %a, double %b, <vscale x 1 x i1> %mask) nounwind {
223 ; CHECK-LABEL: test12:
224 ; CHECK:       # %bb.0: # %entry
225 ; CHECK-NEXT:    vsetivli zero, 9, e64, m1, tu, mu
226 ; CHECK-NEXT:    vfadd.vv v8, v8, v8, v0.t
227 ; CHECK-NEXT:    vfmv.s.f v8, fa0
228 ; CHECK-NEXT:    ret
229 entry:
230   %x = call <vscale x 1 x double> @llvm.riscv.vfadd.mask.nxv1f64.f64(
231     <vscale x 1 x double> %a,
232     <vscale x 1 x double> %a,
233     <vscale x 1 x double> %a,
234     <vscale x 1 x i1> %mask,
235     i64 7,
236     i64 9,
237     i64 0)
238   %y = call <vscale x 1 x double> @llvm.riscv.vfmv.s.f.nxv1f64(
239     <vscale x 1 x double> %x, double %b, i64 2)
240   ret <vscale x 1 x double> %y
243 define <vscale x 1 x double> @test13(<vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {
244 ; CHECK-LABEL: test13:
245 ; CHECK:       # %bb.0: # %entry
246 ; CHECK-NEXT:    vsetvli a0, zero, e64, m1, ta, ma
247 ; CHECK-NEXT:    vfadd.vv v8, v8, v9
248 ; CHECK-NEXT:    ret
249 entry:
250   %0 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(
251     <vscale x 1 x double> undef,
252     <vscale x 1 x double> %a,
253     <vscale x 1 x double> %b,
254     i64 7, i64 -1)
255   ret <vscale x 1 x double> %0
258 define <vscale x 1 x double> @test14(i64 %avl, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {
259 ; CHECK-LABEL: test14:
260 ; CHECK:       # %bb.0: # %entry
261 ; CHECK-NEXT:    vsetvli a0, a0, e32, mf2, ta, ma
262 ; CHECK-NEXT:    vsetivli zero, 1, e64, m1, ta, ma
263 ; CHECK-NEXT:    vfadd.vv v8, v8, v9
264 ; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma
265 ; CHECK-NEXT:    vfadd.vv v8, v8, v9
266 ; CHECK-NEXT:    ret
267 entry:
268   %vsetvli = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 2, i64 7)
269   %f1 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(
270     <vscale x 1 x double> undef,
271     <vscale x 1 x double> %a,
272     <vscale x 1 x double> %b,
273     i64 7, i64 1)
274   %f2 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(
275     <vscale x 1 x double> undef,
276     <vscale x 1 x double> %f1,
277     <vscale x 1 x double> %b,
278     i64 7, i64 %vsetvli)
279   ret <vscale x 1 x double> %f2
282 define <vscale x 1 x double> @test15(i64 %avl, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {
283 ; CHECK-LABEL: test15:
284 ; CHECK:       # %bb.0: # %entry
285 ; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma
286 ; CHECK-NEXT:    vfadd.vv v8, v8, v9
287 ; CHECK-NEXT:    vfadd.vv v8, v8, v9
288 ; CHECK-NEXT:    ret
289 entry:
290   %vsetvli = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 2, i64 7)
291   %f1 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(
292     <vscale x 1 x double> undef,
293     <vscale x 1 x double> %a,
294     <vscale x 1 x double> %b,
295     i64 7, i64 %avl)
296   %f2 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(
297     <vscale x 1 x double> undef,
298     <vscale x 1 x double> %f1,
299     <vscale x 1 x double> %b,
300     i64 7, i64 %vsetvli)
301   ret <vscale x 1 x double> %f2
305 @gdouble = external global double
307 define <vscale x 1 x double> @test16(i64 %avl, double %a, <vscale x 1 x double> %b) nounwind {
308 ; CHECK-LABEL: test16:
309 ; CHECK:       # %bb.0: # %entry
310 ; CHECK-NEXT:    vsetvli a0, a0, e64, mf2, ta, ma
311 ; CHECK-NEXT:    vsetvli a1, zero, e64, m1, ta, ma
312 ; CHECK-NEXT:    vfmv.v.f v9, fa0
313 ; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma
314 ; CHECK-NEXT:    vfadd.vv v8, v9, v8
315 ; CHECK-NEXT:    ret
316 entry:
317   %vsetvli = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 7)
319   %head = insertelement <vscale x 1 x double> poison, double %a, i32 0
320   %splat = shufflevector <vscale x 1 x double> %head, <vscale x 1 x double> poison, <vscale x 1 x i32> zeroinitializer
321   %f2 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(
322     <vscale x 1 x double> undef,
323     <vscale x 1 x double> %splat,
324     <vscale x 1 x double> %b,
325     i64 7, i64 %vsetvli)
326   ret <vscale x 1 x double> %f2
329 define double @test17(i64 %avl, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {
330 ; CHECK-LABEL: test17:
331 ; CHECK:       # %bb.0: # %entry
332 ; CHECK-NEXT:    vsetvli a0, a0, e64, m1, ta, ma
333 ; CHECK-NEXT:    vfmv.f.s fa5, v8
334 ; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma
335 ; CHECK-NEXT:    vfadd.vv v8, v8, v9
336 ; CHECK-NEXT:    vfmv.f.s fa4, v8
337 ; CHECK-NEXT:    fadd.d fa0, fa5, fa4
338 ; CHECK-NEXT:    ret
339 entry:
340   %vsetvli = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 2, i64 7)
341   %c1 = extractelement <vscale x 1 x double> %a, i32 0
342   %f2 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(
343     <vscale x 1 x double> undef,
344     <vscale x 1 x double> %a,
345     <vscale x 1 x double> %b,
346     i64 7, i64 %vsetvli)
347   %c2 = extractelement <vscale x 1 x double> %f2, i32 0
348   %c3 = fadd double %c1, %c2
349   ret double %c3
353 define <vscale x 1 x double> @test18(<vscale x 1 x double> %a, double %b) nounwind {
354 ; CHECK-LABEL: test18:
355 ; CHECK:       # %bb.0: # %entry
356 ; CHECK-NEXT:    vsetivli zero, 6, e64, m1, tu, ma
357 ; CHECK-NEXT:    vmv1r.v v9, v8
358 ; CHECK-NEXT:    vfmv.s.f v9, fa0
359 ; CHECK-NEXT:    vsetvli zero, zero, e64, m1, ta, ma
360 ; CHECK-NEXT:    vfadd.vv v8, v8, v8
361 ; CHECK-NEXT:    vsetvli zero, zero, e64, m1, tu, ma
362 ; CHECK-NEXT:    vfmv.s.f v8, fa0
363 ; CHECK-NEXT:    vsetvli a0, zero, e64, m1, ta, ma
364 ; CHECK-NEXT:    vfadd.vv v8, v9, v8
365 ; CHECK-NEXT:    ret
366 entry:
367   %x = tail call i64 @llvm.riscv.vsetvli(i64 6, i64 3, i64 0)
368   %y = call <vscale x 1 x double> @llvm.riscv.vfmv.s.f.nxv1f64(
369     <vscale x 1 x double> %a, double %b, i64 2)
370   %f2 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(
371     <vscale x 1 x double> undef,
372     <vscale x 1 x double> %a,
373     <vscale x 1 x double> %a,
374     i64 7, i64 %x)
375   %y2 = call <vscale x 1 x double> @llvm.riscv.vfmv.s.f.nxv1f64(
376     <vscale x 1 x double> %f2, double %b, i64 1)
377   %res = fadd <vscale x 1 x double> %y, %y2
378   ret <vscale x 1 x double> %res
381 define <vscale x 1 x double> @test19(<vscale x 1 x double> %a, double %b) nounwind {
382 ; CHECK-LABEL: test19:
383 ; CHECK:       # %bb.0: # %entry
384 ; CHECK-NEXT:    vsetivli zero, 2, e64, m1, tu, ma
385 ; CHECK-NEXT:    vmv1r.v v9, v8
386 ; CHECK-NEXT:    vfmv.s.f v9, fa0
387 ; CHECK-NEXT:    vsetvli a0, zero, e64, m1, ta, ma
388 ; CHECK-NEXT:    vfadd.vv v8, v9, v8
389 ; CHECK-NEXT:    ret
390 entry:
391   %x = tail call i64 @llvm.riscv.vsetvli(i64 6, i64 3, i64 0)
392   %y = call <vscale x 1 x double> @llvm.riscv.vfmv.s.f.nxv1f64(
393     <vscale x 1 x double> %a, double %b, i64 2)
394   %y2 = fadd <vscale x 1 x double> %y, %a
395   ret <vscale x 1 x double> %y2
398 define i64 @avl_forward1(<vscale x 2 x i32> %v, <vscale x 2 x i32>* %p) nounwind {
399 ; CHECK-LABEL: avl_forward1:
400 ; CHECK:       # %bb.0: # %entry
401 ; CHECK-NEXT:    vsetivli a1, 6, e32, m1, ta, ma
402 ; CHECK-NEXT:    vse32.v v8, (a0)
403 ; CHECK-NEXT:    mv a0, a1
404 ; CHECK-NEXT:    ret
405 entry:
406   %vl = tail call i64 @llvm.riscv.vsetvli(i64 6, i64 2, i64 0)
407   call void @llvm.riscv.vse.nxv2i32.i64(<vscale x 2 x i32> %v, <vscale x 2 x i32>* %p, i64 %vl)
408   ret i64 %vl
411 ; Incompatible vtype
412 define i64 @avl_forward1b_neg(<vscale x 2 x i32> %v, <vscale x 2 x i32>* %p) nounwind {
413 ; CHECK-LABEL: avl_forward1b_neg:
414 ; CHECK:       # %bb.0: # %entry
415 ; CHECK-NEXT:    vsetivli a1, 6, e16, m1, ta, ma
416 ; CHECK-NEXT:    vsetvli zero, a1, e32, m1, ta, ma
417 ; CHECK-NEXT:    vse32.v v8, (a0)
418 ; CHECK-NEXT:    mv a0, a1
419 ; CHECK-NEXT:    ret
420 entry:
421   %vl = tail call i64 @llvm.riscv.vsetvli(i64 6, i64 1, i64 0)
422   call void @llvm.riscv.vse.nxv2i32.i64(<vscale x 2 x i32> %v, <vscale x 2 x i32>* %p, i64 %vl)
423   ret i64 %vl
426 define i64 @avl_forward2(<vscale x 2 x i32> %v, <vscale x 2 x i32>* %p) nounwind {
427 ; CHECK-LABEL: avl_forward2:
428 ; CHECK:       # %bb.0: # %entry
429 ; CHECK-NEXT:    vsetvli a1, zero, e32, m1, ta, ma
430 ; CHECK-NEXT:    vse32.v v8, (a0)
431 ; CHECK-NEXT:    mv a0, a1
432 ; CHECK-NEXT:    ret
433 entry:
434   %vl = tail call i64 @llvm.riscv.vsetvlimax(i64 2, i64 0)
435   call void @llvm.riscv.vse.nxv2i32.i64(<vscale x 2 x i32> %v, <vscale x 2 x i32>* %p, i64 %vl)
436   ret i64 %vl
440 ; %vl is intentionally used only once
441 define void @avl_forward3(<vscale x 2 x i32> %v, <vscale x 2 x i32>* %p, i64 %reg) nounwind {
442 ; CHECK-LABEL: avl_forward3:
443 ; CHECK:       # %bb.0: # %entry
444 ; CHECK-NEXT:    vsetvli zero, a1, e32, m1, ta, ma
445 ; CHECK-NEXT:    vse32.v v8, (a0)
446 ; CHECK-NEXT:    ret
447 entry:
448   %vl = tail call i64 @llvm.riscv.vsetvli(i64 %reg, i64 2, i64 0)
449   call void @llvm.riscv.vse.nxv2i32.i64(<vscale x 2 x i32> %v, <vscale x 2 x i32>* %p, i64 %vl)
450   ret void
453 ; %vl has multiple uses
454 define i64 @avl_forward3b(<vscale x 2 x i32> %v, <vscale x 2 x i32>* %p, i64 %reg) nounwind {
455 ; CHECK-LABEL: avl_forward3b:
456 ; CHECK:       # %bb.0: # %entry
457 ; CHECK-NEXT:    vsetvli a1, a1, e32, m1, ta, ma
458 ; CHECK-NEXT:    vse32.v v8, (a0)
459 ; CHECK-NEXT:    mv a0, a1
460 ; CHECK-NEXT:    ret
461 entry:
462   %vl = tail call i64 @llvm.riscv.vsetvli(i64 %reg, i64 2, i64 0)
463   call void @llvm.riscv.vse.nxv2i32.i64(<vscale x 2 x i32> %v, <vscale x 2 x i32>* %p, i64 %vl)
464   ret i64 %vl
467 ; Like4, but with incompatible VTYPE
468 define void @avl_forward4(<vscale x 2 x i32> %v, <vscale x 2 x i32>* %p, i64 %reg) nounwind {
469 ; CHECK-LABEL: avl_forward4:
470 ; CHECK:       # %bb.0: # %entry
471 ; CHECK-NEXT:    vsetvli a1, a1, e16, m1, ta, ma
472 ; CHECK-NEXT:    vsetvli zero, a1, e32, m1, ta, ma
473 ; CHECK-NEXT:    vse32.v v8, (a0)
474 ; CHECK-NEXT:    ret
475 entry:
476   %vl = tail call i64 @llvm.riscv.vsetvli(i64 %reg, i64 1, i64 0)
477   call void @llvm.riscv.vse.nxv2i32.i64(<vscale x 2 x i32> %v, <vscale x 2 x i32>* %p, i64 %vl)
478   ret void
481 ; Like4b, but with incompatible VTYPE
482 define i64 @avl_forward4b(<vscale x 2 x i32> %v, <vscale x 2 x i32>* %p, i64 %reg) nounwind {
483 ; CHECK-LABEL: avl_forward4b:
484 ; CHECK:       # %bb.0: # %entry
485 ; CHECK-NEXT:    vsetvli a1, a1, e16, m1, ta, ma
486 ; CHECK-NEXT:    vsetvli zero, a1, e32, m1, ta, ma
487 ; CHECK-NEXT:    vse32.v v8, (a0)
488 ; CHECK-NEXT:    mv a0, a1
489 ; CHECK-NEXT:    ret
490 entry:
491   %vl = tail call i64 @llvm.riscv.vsetvli(i64 %reg, i64 1, i64 0)
492   call void @llvm.riscv.vse.nxv2i32.i64(<vscale x 2 x i32> %v, <vscale x 2 x i32>* %p, i64 %vl)
493   ret i64 %vl
496 ; Fault first loads can modify VL.
497 ; TODO: The VSETVLI of vadd could be removed here.
498 define <vscale x 1 x i64> @vleNff(i64* %str, i64 %n, i64 %x) {
499 ; CHECK-LABEL: vleNff:
500 ; CHECK:       # %bb.0: # %entry
501 ; CHECK-NEXT:    vsetvli a1, a1, e8, m4, ta, ma
502 ; CHECK-NEXT:    vsetvli zero, a1, e64, m1, ta, ma
503 ; CHECK-NEXT:    vle64ff.v v8, (a0)
504 ; CHECK-NEXT:    vsetvli zero, zero, e64, m1, tu, ma
505 ; CHECK-NEXT:    vadd.vx v8, v8, a2
506 ; CHECK-NEXT:    ret
507 entry:
508   %0 = tail call i64 @llvm.riscv.vsetvli.i64(i64 %n, i64 0, i64 2)
509   %1 = bitcast i64* %str to <vscale x 1 x i64>*
510   %2 = tail call { <vscale x 1 x i64>, i64 } @llvm.riscv.vleff.nxv1i64.i64(<vscale x 1 x i64> undef, <vscale x 1 x i64>* %1, i64 %0)
511   %3 = extractvalue { <vscale x 1 x i64>, i64 } %2, 0
512   %4 = extractvalue { <vscale x 1 x i64>, i64 } %2, 1
513   %5 = tail call <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.i64.i64(<vscale x 1 x i64> %3, <vscale x 1 x i64> %3, i64 %x, i64 %4)
514   ret <vscale x 1 x i64> %5
517 ; Similiar test case, but use same policy for vleff and vadd.
518 ; Note: The test may be redundant if we could fix the TODO of @vleNff.
519 define <vscale x 1 x i64> @vleNff2(i64* %str, i64 %n, i64 %x) {
520 ; CHECK-LABEL: vleNff2:
521 ; CHECK:       # %bb.0: # %entry
522 ; CHECK-NEXT:    vsetvli a1, a1, e8, m4, ta, ma
523 ; CHECK-NEXT:    vsetvli zero, a1, e64, m1, ta, ma
524 ; CHECK-NEXT:    vle64ff.v v8, (a0)
525 ; CHECK-NEXT:    vadd.vx v8, v8, a2
526 ; CHECK-NEXT:    ret
527 entry:
528   %0 = tail call i64 @llvm.riscv.vsetvli.i64(i64 %n, i64 0, i64 2)
529   %1 = bitcast i64* %str to <vscale x 1 x i64>*
530   %2 = tail call { <vscale x 1 x i64>, i64 } @llvm.riscv.vleff.nxv1i64.i64(<vscale x 1 x i64> undef, <vscale x 1 x i64>* %1, i64 %0)
531   %3 = extractvalue { <vscale x 1 x i64>, i64 } %2, 0
532   %4 = extractvalue { <vscale x 1 x i64>, i64 } %2, 1
533   %5 = tail call <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.i64.i64(<vscale x 1 x i64> undef, <vscale x 1 x i64> %3, i64 %x, i64 %4)
534   ret <vscale x 1 x i64> %5
537 declare { <vscale x 1 x i64>, i64 } @llvm.riscv.vleff.nxv1i64.i64(
538   <vscale x 1 x i64>, <vscale x 1 x i64>* nocapture, i64)
540 declare <vscale x 1 x i1> @llvm.riscv.vmseq.nxv1i64.i64.i64(
541   <vscale x 1 x i64>, i64, i64)
543 ; Ensure AVL register is alive when forwarding an AVL immediate that does not fit in 5 bits
544 define <vscale x 2 x i32> @avl_forward5(<vscale x 2 x i32>* %addr) {
545 ; CHECK-LABEL: avl_forward5:
546 ; CHECK:       # %bb.0:
547 ; CHECK-NEXT:    li a1, 32
548 ; CHECK-NEXT:    vsetvli a1, a1, e8, m4, ta, ma
549 ; CHECK-NEXT:    vsetvli zero, a1, e32, m1, ta, ma
550 ; CHECK-NEXT:    vle32.v v8, (a0)
551 ; CHECK-NEXT:    ret
552   %gvl = tail call i64 @llvm.riscv.vsetvli.i64(i64 32, i64 0, i64 2)
553   %ret = tail call <vscale x 2 x i32> @llvm.riscv.vle.nxv2i32.i64(<vscale x 2 x i32> undef, <vscale x 2 x i32>* %addr, i64 %gvl)
554   ret <vscale x 2 x i32> %ret
557 declare <vscale x 1 x double> @llvm.riscv.vfwadd.nxv1f64.nxv1f32.nxv1f32(<vscale x 1 x double>, <vscale x 1 x float>, <vscale x 1 x float>, i64, i64)
559 define <vscale x 1 x double> @test20(i64 %avl, <vscale x 1 x float> %a, <vscale x 1 x float> %b, <vscale x 1 x double> %c) nounwind {
560 ; CHECK-LABEL: test20:
561 ; CHECK:       # %bb.0: # %entry
562 ; CHECK-NEXT:    vsetvli zero, a0, e32, mf2, ta, ma
563 ; CHECK-NEXT:    vfwadd.vv v11, v8, v9
564 ; CHECK-NEXT:    vsetvli zero, zero, e64, m1, ta, ma
565 ; CHECK-NEXT:    vfadd.vv v8, v11, v10
566 ; CHECK-NEXT:    ret
567 entry:
568   %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 2, i64 7)
569   %1 = tail call <vscale x 1 x double> @llvm.riscv.vfwadd.nxv1f64.nxv1f32.nxv1f32(
570     <vscale x 1 x double> undef,
571     <vscale x 1 x float> %a,
572     <vscale x 1 x float> %b,
573     i64 7, i64 %0)
574   %2 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(
575     <vscale x 1 x double> undef,
576     <vscale x 1 x double> %1,
577     <vscale x 1 x double> %c,
578     i64 7, i64 %0)
579   ret <vscale x 1 x double> %2
582 ; This used to fail the machine verifier due to the vsetvli being removed
583 ; while the add was still using it.
584 define i64 @bad_removal(<2 x i64> %arg) {
585 ; CHECK-LABEL: bad_removal:
586 ; CHECK:       # %bb.0: # %bb
587 ; CHECK-NEXT:    vsetivli a0, 16, e64, m1, ta, ma
588 ; CHECK-NEXT:    vmv.x.s a1, v8
589 ; CHECK-NEXT:    add a0, a0, a1
590 ; CHECK-NEXT:    ret
592   %tmp = extractelement <2 x i64> %arg, i64 0
593   %tmp1 = call i64 @llvm.riscv.vsetvli.i64(i64 16, i64 3, i64 0)
594   %tmp2 = add i64 %tmp, %tmp1
595   ret i64 %tmp2
598 declare <vscale x 1 x i64> @llvm.riscv.vadd.mask.nxv1i64.nxv1i64(
599   <vscale x 1 x i64>,
600   <vscale x 1 x i64>,
601   <vscale x 1 x i64>,
602   <vscale x 1 x i1>,
603   i64,
604   i64);
606 declare <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.i64.i64(
607   <vscale x 1 x i64>,
608   <vscale x 1 x i64>,
609   i64,
610   i64);
612 declare <vscale x 1 x double> @llvm.riscv.vfadd.mask.nxv1f64.f64(
613   <vscale x 1 x double>,
614   <vscale x 1 x double>,
615   <vscale x 1 x double>,
616   <vscale x 1 x i1>,
617   i64,
618   i64,
619   i64);
621 declare <vscale x 1 x i64> @llvm.riscv.vmv.s.x.nxv1i64(
622   <vscale x 1 x i64>,
623   i64,
624   i64);
626 declare <vscale x 1 x double> @llvm.riscv.vfmv.s.f.nxv1f64
627   (<vscale x 1 x double>,
628   double,
629   i64)
631 declare i64 @llvm.riscv.vsetvli.i64(i64, i64 immarg, i64 immarg)
632 declare <vscale x 2 x i32> @llvm.riscv.vle.nxv2i32.i64(<vscale x 2 x i32>, <vscale x 2 x i32>* nocapture, i64)
633 declare <vscale x 2 x i1> @llvm.riscv.vmslt.nxv2i32.i32.i64(<vscale x 2 x i32>, i32, i64)
634 declare <vscale x 2 x i1> @llvm.riscv.vmsgt.nxv2i32.i32.i64(<vscale x 2 x i32>, i32, i64)
635 declare <vscale x 2 x i1> @llvm.riscv.vmor.nxv2i1.i64(<vscale x 2 x i1>, <vscale x 2 x i1>, i64)
636 declare void @llvm.riscv.vse.mask.nxv2i32.i64(<vscale x 2 x i32>, <vscale x 2 x i32>* nocapture, <vscale x 2 x i1>, i64)
637 declare void @llvm.riscv.vse.nxv2i32.i64(<vscale x 2 x i32>, <vscale x 2 x i32>* nocapture, i64)