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 vfmsac and vfmsub 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> @vfmsub_vv_v2f16(<2 x half> %va, <2 x half> %vb, <2 x half> %vc) strictfp {
13 ; CHECK-LABEL: vfmsub_vv_v2f16:
15 ; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
16 ; CHECK-NEXT: vfmsub.vv v8, v10, v9
18 %neg = fneg <2 x half> %vb
19 %vd = call <2 x half> @llvm.experimental.constrained.fma.v2f16(<2 x half> %va, <2 x half> %vc, <2 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
23 define <2 x half> @vfmsub_vf_v2f16(<2 x half> %va, <2 x half> %vb, half %c) strictfp {
24 ; CHECK-LABEL: vfmsub_vf_v2f16:
26 ; CHECK-NEXT: vsetivli zero, 2, e16, mf4, ta, ma
27 ; CHECK-NEXT: vfmsac.vf v8, fa0, v9
29 %head = insertelement <2 x half> poison, half %c, i32 0
30 %splat = shufflevector <2 x half> %head, <2 x half> poison, <2 x i32> zeroinitializer
31 %neg = fneg <2 x half> %va
32 %vd = call <2 x half> @llvm.experimental.constrained.fma.v2f16(<2 x half> %vb, <2 x half> %splat, <2 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
36 declare <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half>, <4 x half>, <4 x half>, metadata, metadata)
38 define <4 x half> @vfmsub_vv_v4f16(<4 x half> %va, <4 x half> %vb, <4 x half> %vc) strictfp {
39 ; CHECK-LABEL: vfmsub_vv_v4f16:
41 ; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
42 ; CHECK-NEXT: vfmsub.vv v8, v9, v10
44 %neg = fneg <4 x half> %vc
45 %vd = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %vb, <4 x half> %va, <4 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
49 define <4 x half> @vfmsub_vf_v4f16(<4 x half> %va, <4 x half> %vb, half %c) strictfp {
50 ; CHECK-LABEL: vfmsub_vf_v4f16:
52 ; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma
53 ; CHECK-NEXT: vfmsub.vf v8, fa0, v9
55 %head = insertelement <4 x half> poison, half %c, i32 0
56 %splat = shufflevector <4 x half> %head, <4 x half> poison, <4 x i32> zeroinitializer
57 %neg = fneg <4 x half> %vb
58 %vd = call <4 x half> @llvm.experimental.constrained.fma.v4f16(<4 x half> %va, <4 x half> %splat, <4 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
62 declare <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half>, <8 x half>, <8 x half>, metadata, metadata)
64 define <8 x half> @vfmsub_vv_v8f16(<8 x half> %va, <8 x half> %vb, <8 x half> %vc) strictfp {
65 ; CHECK-LABEL: vfmsub_vv_v8f16:
67 ; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma
68 ; CHECK-NEXT: vfmsac.vv v8, v10, v9
70 %neg = fneg <8 x half> %va
71 %vd = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %vb, <8 x half> %vc, <8 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
75 define <8 x half> @vfmsub_vf_v8f16(<8 x half> %va, <8 x half> %vb, half %c) strictfp {
76 ; CHECK-LABEL: vfmsub_vf_v8f16:
78 ; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, ma
79 ; CHECK-NEXT: vfmsac.vf v8, fa0, v9
81 %head = insertelement <8 x half> poison, half %c, i32 0
82 %splat = shufflevector <8 x half> %head, <8 x half> poison, <8 x i32> zeroinitializer
83 %neg = fneg <8 x half> %va
84 %vd = call <8 x half> @llvm.experimental.constrained.fma.v8f16(<8 x half> %vb, <8 x half> %splat, <8 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
88 declare <16 x half> @llvm.experimental.constrained.fma.v16f16(<16 x half>, <16 x half>, <16 x half>, metadata, metadata)
90 define <16 x half> @vfmsub_vv_v16f16(<16 x half> %va, <16 x half> %vb, <16 x half> %vc) strictfp {
91 ; CHECK-LABEL: vfmsub_vv_v16f16:
93 ; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma
94 ; CHECK-NEXT: vfmsub.vv v8, v12, v10
96 %neg = fneg <16 x half> %vb
97 %vd = call <16 x half> @llvm.experimental.constrained.fma.v16f16(<16 x half> %vc, <16 x half> %va, <16 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
101 define <16 x half> @vfmsub_vf_v16f16(<16 x half> %va, <16 x half> %vb, half %c) strictfp {
102 ; CHECK-LABEL: vfmsub_vf_v16f16:
104 ; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, ma
105 ; CHECK-NEXT: vfmsub.vf v8, fa0, v10
107 %head = insertelement <16 x half> poison, half %c, i32 0
108 %splat = shufflevector <16 x half> %head, <16 x half> poison, <16 x i32> zeroinitializer
109 %neg = fneg <16 x half> %vb
110 %vd = call <16 x half> @llvm.experimental.constrained.fma.v16f16(<16 x half> %va, <16 x half> %splat, <16 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
114 declare <32 x half> @llvm.experimental.constrained.fma.v32f16(<32 x half>, <32 x half>, <32 x half>, metadata, metadata)
116 define <32 x half> @vfmsub_vv_v32f16(<32 x half> %va, <32 x half> %vb, <32 x half> %vc) strictfp {
117 ; CHECK-LABEL: vfmsub_vv_v32f16:
119 ; CHECK-NEXT: li a0, 32
120 ; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma
121 ; CHECK-NEXT: vfmsac.vv v8, v16, v12
123 %neg = fneg <32 x half> %va
124 %vd = call <32 x half> @llvm.experimental.constrained.fma.v32f16(<32 x half> %vc, <32 x half> %vb, <32 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
128 define <32 x half> @vfmsub_vf_v32f16(<32 x half> %va, <32 x half> %vb, half %c) strictfp {
129 ; CHECK-LABEL: vfmsub_vf_v32f16:
131 ; CHECK-NEXT: li a0, 32
132 ; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma
133 ; CHECK-NEXT: vfmsac.vf v8, fa0, v12
135 %head = insertelement <32 x half> poison, half %c, i32 0
136 %splat = shufflevector <32 x half> %head, <32 x half> poison, <32 x i32> zeroinitializer
137 %neg = fneg <32 x half> %va
138 %vd = call <32 x half> @llvm.experimental.constrained.fma.v32f16(<32 x half> %vb, <32 x half> %splat, <32 x half> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
142 declare <2 x float> @llvm.experimental.constrained.fma.v2f32(<2 x float>, <2 x float>, <2 x float>, metadata, metadata)
144 define <2 x float> @vfmsub_vv_v2f32(<2 x float> %va, <2 x float> %vb, <2 x float> %vc) strictfp {
145 ; CHECK-LABEL: vfmsub_vv_v2f32:
147 ; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
148 ; CHECK-NEXT: vfmsub.vv v8, v10, v9
150 %neg = fneg <2 x float> %vb
151 %vd = call <2 x float> @llvm.experimental.constrained.fma.v2f32(<2 x float> %va, <2 x float> %vc, <2 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
155 define <2 x float> @vfmsub_vf_v2f32(<2 x float> %va, <2 x float> %vb, float %c) strictfp {
156 ; CHECK-LABEL: vfmsub_vf_v2f32:
158 ; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
159 ; CHECK-NEXT: vfmsac.vf v8, fa0, v9
161 %head = insertelement <2 x float> poison, float %c, i32 0
162 %splat = shufflevector <2 x float> %head, <2 x float> poison, <2 x i32> zeroinitializer
163 %neg = fneg <2 x float> %va
164 %vd = call <2 x float> @llvm.experimental.constrained.fma.v2f32(<2 x float> %vb, <2 x float> %splat, <2 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
168 declare <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float>, <4 x float>, <4 x float>, metadata, metadata)
170 define <4 x float> @vfmsub_vv_v4f32(<4 x float> %va, <4 x float> %vb, <4 x float> %vc) strictfp {
171 ; CHECK-LABEL: vfmsub_vv_v4f32:
173 ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
174 ; CHECK-NEXT: vfmsub.vv v8, v9, v10
176 %neg = fneg <4 x float> %vc
177 %vd = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> %vb, <4 x float> %va, <4 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
181 define <4 x float> @vfmsub_vf_v4f32(<4 x float> %va, <4 x float> %vb, float %c) strictfp {
182 ; CHECK-LABEL: vfmsub_vf_v4f32:
184 ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
185 ; CHECK-NEXT: vfmsub.vf v8, fa0, v9
187 %head = insertelement <4 x float> poison, float %c, i32 0
188 %splat = shufflevector <4 x float> %head, <4 x float> poison, <4 x i32> zeroinitializer
189 %neg = fneg <4 x float> %vb
190 %vd = call <4 x float> @llvm.experimental.constrained.fma.v4f32(<4 x float> %va, <4 x float> %splat, <4 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
194 declare <8 x float> @llvm.experimental.constrained.fma.v8f32(<8 x float>, <8 x float>, <8 x float>, metadata, metadata)
196 define <8 x float> @vfmsub_vv_v8f32(<8 x float> %va, <8 x float> %vb, <8 x float> %vc) strictfp {
197 ; CHECK-LABEL: vfmsub_vv_v8f32:
199 ; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
200 ; CHECK-NEXT: vfmsac.vv v8, v12, v10
202 %neg = fneg <8 x float> %va
203 %vd = call <8 x float> @llvm.experimental.constrained.fma.v8f32(<8 x float> %vb, <8 x float> %vc, <8 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
207 define <8 x float> @vfmsub_vf_v8f32(<8 x float> %va, <8 x float> %vb, float %c) strictfp {
208 ; CHECK-LABEL: vfmsub_vf_v8f32:
210 ; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, ma
211 ; CHECK-NEXT: vfmsac.vf v8, fa0, v10
213 %head = insertelement <8 x float> poison, float %c, i32 0
214 %splat = shufflevector <8 x float> %head, <8 x float> poison, <8 x i32> zeroinitializer
215 %neg = fneg <8 x float> %va
216 %vd = call <8 x float> @llvm.experimental.constrained.fma.v8f32(<8 x float> %vb, <8 x float> %splat, <8 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
220 declare <16 x float> @llvm.experimental.constrained.fma.v16f32(<16 x float>, <16 x float>, <16 x float>, metadata, metadata)
222 define <16 x float> @vfmsub_vv_v16f32(<16 x float> %va, <16 x float> %vb, <16 x float> %vc) strictfp {
223 ; CHECK-LABEL: vfmsub_vv_v16f32:
225 ; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma
226 ; CHECK-NEXT: vfmsub.vv v8, v16, v12
228 %neg = fneg <16 x float> %vb
229 %vd = call <16 x float> @llvm.experimental.constrained.fma.v16f32(<16 x float> %vc, <16 x float> %va, <16 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
233 define <16 x float> @vfmsub_vf_v16f32(<16 x float> %va, <16 x float> %vb, float %c) strictfp {
234 ; CHECK-LABEL: vfmsub_vf_v16f32:
236 ; CHECK-NEXT: vsetivli zero, 16, e32, m4, ta, ma
237 ; CHECK-NEXT: vfmsub.vf v8, fa0, v12
239 %head = insertelement <16 x float> poison, float %c, i32 0
240 %splat = shufflevector <16 x float> %head, <16 x float> poison, <16 x i32> zeroinitializer
241 %neg = fneg <16 x float> %vb
242 %vd = call <16 x float> @llvm.experimental.constrained.fma.v16f32(<16 x float> %va, <16 x float> %splat, <16 x float> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
246 declare <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double>, <2 x double>, <2 x double>, metadata, metadata)
248 define <2 x double> @vfmsub_vv_v2f64(<2 x double> %va, <2 x double> %vb, <2 x double> %vc) strictfp {
249 ; CHECK-LABEL: vfmsub_vv_v2f64:
251 ; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma
252 ; CHECK-NEXT: vfmsub.vv v8, v10, v9
254 %neg = fneg <2 x double> %vb
255 %vd = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %va, <2 x double> %vc, <2 x double> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
259 define <2 x double> @vfmsub_vf_v2f64(<2 x double> %va, <2 x double> %vb, double %c) strictfp {
260 ; CHECK-LABEL: vfmsub_vf_v2f64:
262 ; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma
263 ; CHECK-NEXT: vfmsac.vf v8, fa0, v9
265 %head = insertelement <2 x double> poison, double %c, i32 0
266 %splat = shufflevector <2 x double> %head, <2 x double> poison, <2 x i32> zeroinitializer
267 %neg = fneg <2 x double> %va
268 %vd = call <2 x double> @llvm.experimental.constrained.fma.v2f64(<2 x double> %vb, <2 x double> %splat, <2 x double> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
272 declare <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double>, <4 x double>, <4 x double>, metadata, metadata)
274 define <4 x double> @vfmsub_vv_v4f64(<4 x double> %va, <4 x double> %vb, <4 x double> %vc) strictfp {
275 ; CHECK-LABEL: vfmsub_vv_v4f64:
277 ; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma
278 ; CHECK-NEXT: vfmsub.vv v8, v10, v12
280 %neg = fneg <4 x double> %vc
281 %vd = call <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double> %vb, <4 x double> %va, <4 x double> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
285 define <4 x double> @vfmsub_vf_v4f64(<4 x double> %va, <4 x double> %vb, double %c) strictfp {
286 ; CHECK-LABEL: vfmsub_vf_v4f64:
288 ; CHECK-NEXT: vsetivli zero, 4, e64, m2, ta, ma
289 ; CHECK-NEXT: vfmsub.vf v8, fa0, v10
291 %head = insertelement <4 x double> poison, double %c, i32 0
292 %splat = shufflevector <4 x double> %head, <4 x double> poison, <4 x i32> zeroinitializer
293 %neg = fneg <4 x double> %vb
294 %vd = call <4 x double> @llvm.experimental.constrained.fma.v4f64(<4 x double> %va, <4 x double> %splat, <4 x double> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
298 declare <8 x double> @llvm.experimental.constrained.fma.v8f64(<8 x double>, <8 x double>, <8 x double>, metadata, metadata)
300 define <8 x double> @vfmsub_vv_v8f64(<8 x double> %va, <8 x double> %vb, <8 x double> %vc) strictfp {
301 ; CHECK-LABEL: vfmsub_vv_v8f64:
303 ; CHECK-NEXT: vsetivli zero, 8, e64, m4, ta, ma
304 ; CHECK-NEXT: vfmsac.vv v8, v16, v12
306 %neg = fneg <8 x double> %va
307 %vd = call <8 x double> @llvm.experimental.constrained.fma.v8f64(<8 x double> %vb, <8 x double> %vc, <8 x double> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")
311 define <8 x double> @vfmsub_vf_v8f64(<8 x double> %va, <8 x double> %vb, double %c) strictfp {
312 ; CHECK-LABEL: vfmsub_vf_v8f64:
314 ; CHECK-NEXT: vsetivli zero, 8, e64, m4, ta, ma
315 ; CHECK-NEXT: vfmsac.vf v8, fa0, v12
317 %head = insertelement <8 x double> poison, double %c, i32 0
318 %splat = shufflevector <8 x double> %head, <8 x double> poison, <8 x i32> zeroinitializer
319 %neg = fneg <8 x double> %va
320 %vd = call <8 x double> @llvm.experimental.constrained.fma.v8f64(<8 x double> %vb, <8 x double> %splat, <8 x double> %neg, metadata !"round.dynamic", metadata !"fpexcept.strict")