1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -mattr=+d,+zfh,+zvfh,+v -target-abi=ilp32d \
3 ; RUN: -verify-machineinstrs < %s | FileCheck %s
4 ; RUN: llc -mtriple=riscv64 -mattr=+d,+zfh,+zvfh,+v -target-abi=lp64d \
5 ; RUN: -verify-machineinstrs < %s | FileCheck %s
7 ; This tests a mix of vfmacc and vfmadd by using different operand orders to
8 ; trigger commuting in TwoAddressInstructionPass.
10 declare <2 x half> @llvm.experimental.constrained.fma.v2f16(<2 x half>, <2 x half>, <2 x half>, metadata, metadata)
12 define <2 x half> @vfmadd_vv_v2f16(<2 x half> %va, <2 x half> %vb, <2 x half> %vc) strictfp {
13 ; CHECK-LABEL: vfmadd_vv_v2f16:
15 ; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
16 ; CHECK-NEXT: vfmadd.vv v8, v10, v9
18 %vd = call <2 x half> @llvm.experimental.constrained.fma.v2f16(<2 x half> %va, <2 x half> %vc, <2 x half> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict")
22 define <2 x half> @vfmadd_vf_v2f16(<2 x half> %va, <2 x half> %vb, half %c) strictfp {
23 ; CHECK-LABEL: vfmadd_vf_v2f16:
25 ; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
26 ; CHECK-NEXT: vfmacc.vf v8, fa0, v9
28 %head = insertelement <2 x half> poison, half %c, i32 0
29 %splat = shufflevector <2 x half> %head, <2 x half> poison, <2 x i32> zeroinitializer
30 %vd = call <2 x half> @llvm.experimental.constrained.fma.v2f16(<2 x half> %vb, <2 x half> %splat, <2 x half> %va, metadata !"round.dynamic", metadata !"fpexcept.strict")
34 declare <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half>, <4 x half>, <4 x half>, metadata, metadata)
36 define <4 x half> @vfmadd_vv_v4f16(<4 x half> %va, <4 x half> %vb, <4 x half> %vc) strictfp {
37 ; CHECK-LABEL: vfmadd_vv_v4f16:
39 ; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
40 ; CHECK-NEXT: vfmadd.vv v8, v9, v10
42 %vd = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %vb, <4 x half> %va, <4 x half> %vc, metadata !"round.dynamic", metadata !"fpexcept.strict")
46 define <4 x half> @vfmadd_vf_v4f16(<4 x half> %va, <4 x half> %vb, half %c) strictfp {
47 ; CHECK-LABEL: vfmadd_vf_v4f16:
49 ; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
50 ; CHECK-NEXT: vfmadd.vf v8, fa0, v9
52 %head = insertelement <4 x half> poison, half %c, i32 0
53 %splat = shufflevector <4 x half> %head, <4 x half> poison, <4 x i32> zeroinitializer
54 %vd = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %va, <4 x half> %splat, <4 x half> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict")
58 declare <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half>, <8 x half>, <8 x half>, metadata, metadata)
60 define <8 x half> @vfmadd_vv_v8f16(<8 x half> %va, <8 x half> %vb, <8 x half> %vc) strictfp {
61 ; CHECK-LABEL: vfmadd_vv_v8f16:
63 ; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma
64 ; CHECK-NEXT: vfmacc.vv v8, v10, v9
66 %vd = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %vb, <8 x half> %vc, <8 x half> %va, metadata !"round.dynamic", metadata !"fpexcept.strict")
70 define <8 x half> @vfmadd_vf_v8f16(<8 x half> %va, <8 x half> %vb, half %c) strictfp {
71 ; CHECK-LABEL: vfmadd_vf_v8f16:
73 ; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma
74 ; CHECK-NEXT: vfmacc.vf v8, fa0, v9
76 %head = insertelement <8 x half> poison, half %c, i32 0
77 %splat = shufflevector <8 x half> %head, <8 x half> poison, <8 x i32> zeroinitializer
78 %vd = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %vb, <8 x half> %splat, <8 x half> %va, metadata !"round.dynamic", metadata !"fpexcept.strict")
82 declare <16 x half> @llvm.experimental.constrained.fma.v16f16(<16 x half>, <16 x half>, <16 x half>, metadata, metadata)
84 define <16 x half> @vfmadd_vv_v16f16(<16 x half> %va, <16 x half> %vb, <16 x half> %vc) strictfp {
85 ; CHECK-LABEL: vfmadd_vv_v16f16:
87 ; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma
88 ; CHECK-NEXT: vfmadd.vv v8, v12, v10
90 %vd = call <16 x half> @llvm.experimental.constrained.fma.v16f16(<16 x half> %vc, <16 x half> %va, <16 x half> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict")
94 define <16 x half> @vfmadd_vf_v16f16(<16 x half> %va, <16 x half> %vb, half %c) strictfp {
95 ; CHECK-LABEL: vfmadd_vf_v16f16:
97 ; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma
98 ; CHECK-NEXT: vfmadd.vf v8, fa0, v10
100 %head = insertelement <16 x half> poison, half %c, i32 0
101 %splat = shufflevector <16 x half> %head, <16 x half> poison, <16 x i32> zeroinitializer
102 %vd = call <16 x half> @llvm.experimental.constrained.fma.v16f16(<16 x half> %va, <16 x half> %splat, <16 x half> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict")
106 declare <32 x half> @llvm.experimental.constrained.fma.v32f16(<32 x half>, <32 x half>, <32 x half>, metadata, metadata)
108 define <32 x half> @vfmadd_vv_v32f16(<32 x half> %va, <32 x half> %vb, <32 x half> %vc) strictfp {
109 ; CHECK-LABEL: vfmadd_vv_v32f16:
111 ; CHECK-NEXT: li a0, 32
112 ; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma
113 ; CHECK-NEXT: vfmacc.vv v8, v16, v12
115 %vd = call <32 x half> @llvm.experimental.constrained.fma.v32f16(<32 x half> %vc, <32 x half> %vb, <32 x half> %va, metadata !"round.dynamic", metadata !"fpexcept.strict")
119 define <32 x half> @vfmadd_vf_v32f16(<32 x half> %va, <32 x half> %vb, half %c) strictfp {
120 ; CHECK-LABEL: vfmadd_vf_v32f16:
122 ; CHECK-NEXT: li a0, 32
123 ; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma
124 ; CHECK-NEXT: vfmacc.vf v8, fa0, v12
126 %head = insertelement <32 x half> poison, half %c, i32 0
127 %splat = shufflevector <32 x half> %head, <32 x half> poison, <32 x i32> zeroinitializer
128 %vd = call <32 x half> @llvm.experimental.constrained.fma.v32f16(<32 x half> %vb, <32 x half> %splat, <32 x half> %va, metadata !"round.dynamic", metadata !"fpexcept.strict")
132 declare <2 x float> @llvm.experimental.constrained.fma.v2f32(<2 x float>, <2 x float>, <2 x float>, metadata, metadata)
134 define <2 x float> @vfmadd_vv_v2f32(<2 x float> %va, <2 x float> %vb, <2 x float> %vc) strictfp {
135 ; CHECK-LABEL: vfmadd_vv_v2f32:
137 ; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
138 ; CHECK-NEXT: vfmadd.vv v8, v10, v9
140 %vd = call <2 x float> @llvm.experimental.constrained.fma.v2f32(<2 x float> %va, <2 x float> %vc, <2 x float> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict")
144 define <2 x float> @vfmadd_vf_v2f32(<2 x float> %va, <2 x float> %vb, float %c) strictfp {
145 ; CHECK-LABEL: vfmadd_vf_v2f32:
147 ; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
148 ; CHECK-NEXT: vfmacc.vf v8, fa0, v9
150 %head = insertelement <2 x float> poison, float %c, i32 0
151 %splat = shufflevector <2 x float> %head, <2 x float> poison, <2 x i32> zeroinitializer
152 %vd = call <2 x float> @llvm.experimental.constrained.fma.v2f32(<2 x float> %vb, <2 x float> %splat, <2 x float> %va, metadata !"round.dynamic", metadata !"fpexcept.strict")
156 declare <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float>, <4 x float>, <4 x float>, metadata, metadata)
158 define <4 x float> @vfmadd_vv_v4f32(<4 x float> %va, <4 x float> %vb, <4 x float> %vc) strictfp {
159 ; CHECK-LABEL: vfmadd_vv_v4f32:
161 ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
162 ; CHECK-NEXT: vfmadd.vv v8, v9, v10
164 %vd = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> %vb, <4 x float> %va, <4 x float> %vc, metadata !"round.dynamic", metadata !"fpexcept.strict")
168 define <4 x float> @vfmadd_vf_v4f32(<4 x float> %va, <4 x float> %vb, float %c) strictfp {
169 ; CHECK-LABEL: vfmadd_vf_v4f32:
171 ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
172 ; CHECK-NEXT: vfmadd.vf v8, fa0, v9
174 %head = insertelement <4 x float> poison, float %c, i32 0
175 %splat = shufflevector <4 x float> %head, <4 x float> poison, <4 x i32> zeroinitializer
176 %vd = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> %va, <4 x float> %splat, <4 x float> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict")
180 declare <8 x float> @llvm.experimental.constrained.fma.v8f32(<8 x float>, <8 x float>, <8 x float>, metadata, metadata)
182 define <8 x float> @vfmadd_vv_v8f32(<8 x float> %va, <8 x float> %vb, <8 x float> %vc) strictfp {
183 ; CHECK-LABEL: vfmadd_vv_v8f32:
185 ; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
186 ; CHECK-NEXT: vfmacc.vv v8, v12, v10
188 %vd = call <8 x float> @llvm.experimental.constrained.fma.v8f32(<8 x float> %vb, <8 x float> %vc, <8 x float> %va, metadata !"round.dynamic", metadata !"fpexcept.strict")
192 define <8 x float> @vfmadd_vf_v8f32(<8 x float> %va, <8 x float> %vb, float %c) strictfp {
193 ; CHECK-LABEL: vfmadd_vf_v8f32:
195 ; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
196 ; CHECK-NEXT: vfmacc.vf v8, fa0, v10
198 %head = insertelement <8 x float> poison, float %c, i32 0
199 %splat = shufflevector <8 x float> %head, <8 x float> poison, <8 x i32> zeroinitializer
200 %vd = call <8 x float> @llvm.experimental.constrained.fma.v8f32(<8 x float> %vb, <8 x float> %splat, <8 x float> %va, metadata !"round.dynamic", metadata !"fpexcept.strict")
204 declare <16 x float> @llvm.experimental.constrained.fma.v16f32(<16 x float>, <16 x float>, <16 x float>, metadata, metadata)
206 define <16 x float> @vfmadd_vv_v16f32(<16 x float> %va, <16 x float> %vb, <16 x float> %vc) strictfp {
207 ; CHECK-LABEL: vfmadd_vv_v16f32:
209 ; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma
210 ; CHECK-NEXT: vfmadd.vv v8, v16, v12
212 %vd = call <16 x float> @llvm.experimental.constrained.fma.v16f32(<16 x float> %vc, <16 x float> %va, <16 x float> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict")
216 define <16 x float> @vfmadd_vf_v16f32(<16 x float> %va, <16 x float> %vb, float %c) strictfp {
217 ; CHECK-LABEL: vfmadd_vf_v16f32:
219 ; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma
220 ; CHECK-NEXT: vfmadd.vf v8, fa0, v12
222 %head = insertelement <16 x float> poison, float %c, i32 0
223 %splat = shufflevector <16 x float> %head, <16 x float> poison, <16 x i32> zeroinitializer
224 %vd = call <16 x float> @llvm.experimental.constrained.fma.v16f32(<16 x float> %va, <16 x float> %splat, <16 x float> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict")
228 declare <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double>, <2 x double>, <2 x double>, metadata, metadata)
230 define <2 x double> @vfmadd_vv_v2f64(<2 x double> %va, <2 x double> %vb, <2 x double> %vc) strictfp {
231 ; CHECK-LABEL: vfmadd_vv_v2f64:
233 ; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma
234 ; CHECK-NEXT: vfmadd.vv v8, v10, v9
236 %vd = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %va, <2 x double> %vc, <2 x double> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict")
240 define <2 x double> @vfmadd_vf_v2f64(<2 x double> %va, <2 x double> %vb, double %c) strictfp {
241 ; CHECK-LABEL: vfmadd_vf_v2f64:
243 ; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma
244 ; CHECK-NEXT: vfmacc.vf v8, fa0, v9
246 %head = insertelement <2 x double> poison, double %c, i32 0
247 %splat = shufflevector <2 x double> %head, <2 x double> poison, <2 x i32> zeroinitializer
248 %vd = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %vb, <2 x double> %splat, <2 x double> %va, metadata !"round.dynamic", metadata !"fpexcept.strict")
252 declare <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double>, <4 x double>, <4 x double>, metadata, metadata)
254 define <4 x double> @vfmadd_vv_v4f64(<4 x double> %va, <4 x double> %vb, <4 x double> %vc) strictfp {
255 ; CHECK-LABEL: vfmadd_vv_v4f64:
257 ; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma
258 ; CHECK-NEXT: vfmadd.vv v8, v10, v12
260 %vd = call <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double> %vb, <4 x double> %va, <4 x double> %vc, metadata !"round.dynamic", metadata !"fpexcept.strict")
264 define <4 x double> @vfmadd_vf_v4f64(<4 x double> %va, <4 x double> %vb, double %c) strictfp {
265 ; CHECK-LABEL: vfmadd_vf_v4f64:
267 ; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma
268 ; CHECK-NEXT: vfmadd.vf v8, fa0, v10
270 %head = insertelement <4 x double> poison, double %c, i32 0
271 %splat = shufflevector <4 x double> %head, <4 x double> poison, <4 x i32> zeroinitializer
272 %vd = call <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double> %va, <4 x double> %splat, <4 x double> %vb, metadata !"round.dynamic", metadata !"fpexcept.strict")
276 declare <8 x double> @llvm.experimental.constrained.fma.v8f64(<8 x double>, <8 x double>, <8 x double>, metadata, metadata)
278 define <8 x double> @vfmadd_vv_v8f64(<8 x double> %va, <8 x double> %vb, <8 x double> %vc) strictfp {
279 ; CHECK-LABEL: vfmadd_vv_v8f64:
281 ; CHECK-NEXT: vsetivli zero, 8, e64, m4, ta, ma
282 ; CHECK-NEXT: vfmacc.vv v8, v16, v12
284 %vd = call <8 x double> @llvm.experimental.constrained.fma.v8f64(<8 x double> %vb, <8 x double> %vc, <8 x double> %va, metadata !"round.dynamic", metadata !"fpexcept.strict")
288 define <8 x double> @vfmadd_vf_v8f64(<8 x double> %va, <8 x double> %vb, double %c) strictfp {
289 ; CHECK-LABEL: vfmadd_vf_v8f64:
291 ; CHECK-NEXT: vsetivli zero, 8, e64, m4, ta, ma
292 ; CHECK-NEXT: vfmacc.vf v8, fa0, v12
294 %head = insertelement <8 x double> poison, double %c, i32 0
295 %splat = shufflevector <8 x double> %head, <8 x double> poison, <8 x i32> zeroinitializer
296 %vd = call <8 x double> @llvm.experimental.constrained.fma.v8f64(<8 x double> %vb, <8 x double> %splat, <8 x double> %va, metadata !"round.dynamic", metadata !"fpexcept.strict")