1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2 ; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+v -verify-machineinstrs | FileCheck %s
3 ; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+v -verify-machineinstrs | FileCheck %s
5 declare <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32>, <vscale x 4 x i32>, iXLen)
7 declare <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, iXLen)
9 define <vscale x 4 x i32> @vadd(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl1, iXLen %vl2) {
12 ; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma
13 ; CHECK-NEXT: vadd.vv v10, v10, v12
14 ; CHECK-NEXT: vsetvli zero, a1, e32, m2, tu, ma
15 ; CHECK-NEXT: vmv.v.v v8, v10
17 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl1)
18 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen %vl2)
19 ret <vscale x 4 x i32> %w
22 define <vscale x 4 x i32> @vadd_mask(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i1> %m, iXLen %vl) {
23 ; CHECK-LABEL: vadd_mask:
25 ; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, mu
26 ; CHECK-NEXT: vadd.vv v8, v10, v12, v0.t
28 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.mask.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i1> %m, iXLen %vl, iXLen 3)
29 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen %vl)
30 ret <vscale x 4 x i32> %w
33 define <vscale x 4 x i32> @vadd_undef(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl1, iXLen %vl2) {
34 ; CHECK-LABEL: vadd_undef:
36 ; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma
37 ; CHECK-NEXT: vadd.vv v8, v8, v10
38 ; CHECK-NEXT: vsetvli zero, a1, e32, m2, ta, ma
39 ; CHECK-NEXT: vmv.v.v v8, v8
41 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl1)
42 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %v, iXLen %vl2)
43 ret <vscale x 4 x i32> %w
46 ; TODO: Is this correct if there's already a passthru in the src?
47 define <vscale x 4 x i32> @vadd_same_passthru(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl1, iXLen %vl2) {
48 ; CHECK-LABEL: vadd_same_passthru:
50 ; CHECK-NEXT: vmv2r.v v14, v8
51 ; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma
52 ; CHECK-NEXT: vadd.vv v14, v10, v12
53 ; CHECK-NEXT: vsetvli zero, a1, e32, m2, tu, ma
54 ; CHECK-NEXT: vmv.v.v v8, v14
56 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.nxv4i32.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, iXLen %vl1)
57 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen %vl2)
58 ret <vscale x 4 x i32> %w
61 declare <vscale x 4 x i32> @llvm.riscv.vadd.mask.nxv4i32.nxv4i32(<vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i32>, <vscale x 4 x i1>, iXLen, iXLen)
63 define <vscale x 4 x i32> @vadd_mask_ma(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i1> %mask, iXLen %vl1, iXLen %vl2) {
64 ; CHECK-LABEL: vadd_mask_ma:
66 ; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma
67 ; CHECK-NEXT: vadd.vv v10, v10, v12, v0.t
68 ; CHECK-NEXT: vsetvli zero, a1, e32, m2, tu, ma
69 ; CHECK-NEXT: vmv.v.v v8, v10
71 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.mask.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i1> %mask, iXLen %vl1, iXLen 2)
72 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen %vl2)
73 ret <vscale x 4 x i32> %w
76 define <vscale x 4 x i32> @vadd_mask_mu(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i1> %mask, iXLen %vl1, iXLen %vl2) {
77 ; CHECK-LABEL: vadd_mask_mu:
79 ; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma
80 ; CHECK-NEXT: vadd.vv v10, v10, v12, v0.t
81 ; CHECK-NEXT: vsetvli zero, a1, e32, m2, tu, ma
82 ; CHECK-NEXT: vmv.v.v v8, v10
84 %v = call <vscale x 4 x i32> @llvm.riscv.vadd.mask.nxv4i32.nxv4i32(<vscale x 4 x i32> poison, <vscale x 4 x i32> %a, <vscale x 4 x i32> %b, <vscale x 4 x i1> %mask, iXLen %vl1, iXLen 0)
85 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen %vl2)
86 ret <vscale x 4 x i32> %w
89 declare <vscale x 4 x i32> @llvm.riscv.vle.nxv4i32(<vscale x 4 x i32>, ptr, iXLen)
91 define <vscale x 4 x i32> @foldable_load(<vscale x 4 x i32> %passthru, ptr %p) {
92 ; CHECK-LABEL: foldable_load:
94 ; CHECK-NEXT: vsetivli zero, 2, e32, m2, tu, ma
95 ; CHECK-NEXT: vle32.v v8, (a0)
97 %v = call <vscale x 4 x i32> @llvm.riscv.vle.nxv4i32(<vscale x 4 x i32> poison, ptr %p, iXLen 4)
98 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen 2)
99 ret <vscale x 4 x i32> %w
102 ; Can't fold this as the VLs aren't constant.
103 define <vscale x 4 x i32> @unfoldable_load(<vscale x 4 x i32> %passthru, ptr %p, iXLen %vl1, iXLen %vl2) {
104 ; CHECK-LABEL: unfoldable_load:
106 ; CHECK-NEXT: vsetvli zero, a1, e32, m2, ta, ma
107 ; CHECK-NEXT: vle32.v v10, (a0)
108 ; CHECK-NEXT: vsetvli zero, a2, e32, m2, tu, ma
109 ; CHECK-NEXT: vmv.v.v v8, v10
111 %v = call <vscale x 4 x i32> @llvm.riscv.vle.nxv4i32(<vscale x 4 x i32> poison, ptr %p, iXLen %vl1)
112 %w = call <vscale x 4 x i32> @llvm.riscv.vmv.v.v.nxv4i32(<vscale x 4 x i32> %passthru, <vscale x 4 x i32> %v, iXLen %vl2)
113 ret <vscale x 4 x i32> %w
116 declare <vscale x 4 x float> @llvm.riscv.vmv.v.v.nxv4f32(<vscale x 4 x float>, <vscale x 4 x float>, iXLen)
118 declare <vscale x 4 x float> @llvm.riscv.vfadd.nxv4f32.nxv4f32(<vscale x 4 x float>, <vscale x 4 x float>, <vscale x 4 x float>, iXLen, iXLen)
120 define <vscale x 4 x float> @unfoldable_vfadd(<vscale x 4 x float> %passthru, <vscale x 4 x float> %a, <vscale x 4 x float> %b, iXLen %vl1, iXLen %vl2) {
121 ; CHECK-LABEL: unfoldable_vfadd:
123 ; CHECK-NEXT: vsetvli zero, a0, e32, m2, ta, ma
124 ; CHECK-NEXT: vfadd.vv v10, v10, v12
125 ; CHECK-NEXT: vsetvli zero, a1, e32, m2, tu, ma
126 ; CHECK-NEXT: vmv.v.v v8, v10
128 %v = call <vscale x 4 x float> @llvm.riscv.vfadd.nxv4f32.nxv4f32(<vscale x 4 x float> poison, <vscale x 4 x float> %a, <vscale x 4 x float> %b, iXLen 7, iXLen %vl1)
129 %w = call <vscale x 4 x float> @llvm.riscv.vmv.v.v.nxv4f32(<vscale x 4 x float> %passthru, <vscale x 4 x float> %v, iXLen %vl2)
130 ret <vscale x 4 x float> %w
133 define <vscale x 4 x float> @foldable_vfadd(<vscale x 4 x float> %passthru, <vscale x 4 x float> %a, <vscale x 4 x float> %b, iXLen %vl) {
134 ; CHECK-LABEL: foldable_vfadd:
136 ; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma
137 ; CHECK-NEXT: vfadd.vv v8, v10, v12
139 %v = call <vscale x 4 x float> @llvm.riscv.vfadd.nxv4f32.nxv4f32(<vscale x 4 x float> poison, <vscale x 4 x float> %a, <vscale x 4 x float> %b, iXLen 7, iXLen %vl)
140 %w = call <vscale x 4 x float> @llvm.riscv.vmv.v.v.nxv4f32(<vscale x 4 x float> %passthru, <vscale x 4 x float> %v, iXLen %vl)
141 ret <vscale x 4 x float> %w
144 ; This shouldn't be folded because we need to preserve exceptions with
145 ; "fpexcept.strict" exception behaviour, and changing the VL may hide them.
146 define <vscale x 4 x float> @unfoldable_constrained_fadd(<vscale x 4 x float> %passthru, <vscale x 4 x float> %x, <vscale x 4 x float> %y, iXLen %vl) strictfp {
147 ; CHECK-LABEL: unfoldable_constrained_fadd:
149 ; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, ma
150 ; CHECK-NEXT: vfadd.vv v10, v10, v12
151 ; CHECK-NEXT: vsetvli zero, a0, e32, m2, tu, ma
152 ; CHECK-NEXT: vmv.v.v v8, v10
154 %a = call <vscale x 4 x float> @llvm.experimental.constrained.fadd(<vscale x 4 x float> %x, <vscale x 4 x float> %y, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp
155 %b = call <vscale x 4 x float> @llvm.riscv.vmv.v.v.nxv4f32(<vscale x 4 x float> %passthru, <vscale x 4 x float> %a, iXLen %vl) strictfp
156 ret <vscale x 4 x float> %b
159 define <vscale x 2 x i32> @unfoldable_vredsum(<vscale x 2 x i32> %passthru, <vscale x 4 x i32> %x, <vscale x 2 x i32> %y) {
160 ; CHECK-LABEL: unfoldable_vredsum:
162 ; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, ma
163 ; CHECK-NEXT: vredsum.vs v9, v10, v9
164 ; CHECK-NEXT: vsetivli zero, 1, e32, m1, tu, ma
165 ; CHECK-NEXT: vmv.v.v v8, v9
167 %a = call <vscale x 2 x i32> @llvm.riscv.vredsum.nxv2i32.nxv4i32(<vscale x 2 x i32> poison, <vscale x 4 x i32> %x, <vscale x 2 x i32> %y, iXLen -1)
168 %b = call <vscale x 2 x i32> @llvm.riscv.vmv.v.v.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %a, iXLen 1)
169 ret <vscale x 2 x i32> %b
172 define <vscale x 2 x i32> @unfoldable_mismatched_sew(<vscale x 2 x i32> %passthru, <vscale x 1 x i64> %x, <vscale x 1 x i64> %y, iXLen %avl) {
173 ; CHECK-LABEL: unfoldable_mismatched_sew:
175 ; CHECK-NEXT: vsetvli zero, a0, e64, m1, ta, ma
176 ; CHECK-NEXT: vadd.vv v9, v9, v10
177 ; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, ma
178 ; CHECK-NEXT: vmv.v.v v8, v9
180 %a = call <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.nxv1i64(<vscale x 1 x i64> poison, <vscale x 1 x i64> %x, <vscale x 1 x i64> %y, iXLen %avl)
181 %a.bitcast = bitcast <vscale x 1 x i64> %a to <vscale x 2 x i32>
182 %b = call <vscale x 2 x i32> @llvm.riscv.vmv.v.v.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %a.bitcast, iXLen %avl)
183 ret <vscale x 2 x i32> %b