Skip to content

Commit 1c3a667

Browse files
committed
Recommit "[RISCV] Add intrinsics for vfmv.f.s and vfmv.s.f"
This time with tests. Original message: Similar to D93365, but for floating point. No need for special ISD opcodes though. We can directly isel these from intrinsics. I had to use anyfloat_ty instead of anyvector_ty in the intrinsics to make LLVMVectorElementType not crash when imported into the -gen-dag-isel tablegen backend. Differential Revision: https://reviews.llvm.org/D93426
1 parent cd3e811 commit 1c3a667

File tree

6 files changed

+678
-3
lines changed

6 files changed

+678
-3
lines changed

llvm/include/llvm/IR/IntrinsicsRISCV.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,4 +349,12 @@ let TargetPrefix = "riscv" in {
349349
[IntrNoMem]>, RISCVVIntrinsic {
350350
let ExtendOperand = 2;
351351
}
352+
353+
def int_riscv_vfmv_f_s : Intrinsic<[LLVMVectorElementType<0>],
354+
[llvm_anyfloat_ty],
355+
[IntrNoMem]>, RISCVVIntrinsic;
356+
def int_riscv_vfmv_s_f : Intrinsic<[llvm_anyfloat_ty],
357+
[LLVMMatchType<0>, LLVMVectorElementType<0>,
358+
llvm_anyint_ty],
359+
[IntrNoMem]>, RISCVVIntrinsic;
352360
} // TargetPrefix = "riscv"

llvm/lib/Target/RISCV/RISCVInstrInfoV.td

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -980,8 +980,9 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0, vm = 1 in {
980980
// Floating-Point Scalar Move Instructions
981981
def VFMV_F_S : RVInstV<0b010000, 0b00000, OPFVV, (outs FPR32:$vd),
982982
(ins VR:$vs2), "vfmv.f.s", "$vd, $vs2">;
983-
def VFMV_S_F : RVInstV2<0b010000, 0b00000, OPFVF, (outs VR:$vd),
984-
(ins FPR32:$rs1), "vfmv.s.f", "$vd, $rs1">;
983+
let Constraints = "$vd = $vd_wb" in
984+
def VFMV_S_F : RVInstV2<0b010000, 0b00000, OPFVF, (outs VR:$vd_wb),
985+
(ins VR:$vd, FPR32:$rs1), "vfmv.s.f", "$vd, $rs1">;
985986

986987
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0, vm = 1
987988
} // Predicates = [HasStdExtV, HasStdExtF]

llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1370,12 +1370,37 @@ let mayLoad = 0, mayStore = 0, hasSideEffects = 0, usesCustomInserter = 1,
13701370
Constraints = "$rd = $rs1" in
13711371
def PseudoVMV_S_X # "_" # m.MX: Pseudo<(outs m.vrclass:$rd),
13721372
(ins m.vrclass:$rs1, GPR:$rs2,
1373-
GPR:$vl, ixlenimm:$sew),
1373+
GPR:$vl, ixlenimm:$sew),
13741374
[]>, RISCVVPseudo;
13751375
}
13761376
}
13771377
}
1378+
} // Predicates = [HasStdExtV]
1379+
1380+
//===----------------------------------------------------------------------===//
1381+
// 17.2. Floating-Point Scalar Move Instructions
1382+
//===----------------------------------------------------------------------===//
1383+
1384+
let Predicates = [HasStdExtV, HasStdExtF] in {
1385+
let mayLoad = 0, mayStore = 0, hasSideEffects = 0, usesCustomInserter = 1,
1386+
Uses = [VL, VTYPE] in {
1387+
foreach m = MxList.m in {
1388+
let VLMul = m.value in {
1389+
let SEWIndex = 2, BaseInstr = VFMV_F_S in
1390+
def PseudoVFMV_F_S # "_" # m.MX : Pseudo<(outs FPR32:$rd),
1391+
(ins m.vrclass:$rs2,
1392+
ixlenimm:$sew),
1393+
[]>, RISCVVPseudo;
1394+
let VLIndex = 3, SEWIndex = 4, BaseInstr = VFMV_S_F,
1395+
Constraints = "$rd = $rs1" in
1396+
def PseudoVFMV_S_F # "_" # m.MX : Pseudo<(outs m.vrclass:$rd),
1397+
(ins m.vrclass:$rs1, FPR32:$rs2,
1398+
GPR:$vl, ixlenimm:$sew),
1399+
[]>, RISCVVPseudo;
1400+
}
1401+
}
13781402
}
1403+
} // Predicates = [HasStdExtV, HasStdExtF]
13791404

13801405
//===----------------------------------------------------------------------===//
13811406
// Patterns.
@@ -1557,3 +1582,34 @@ foreach vti = AllIntegerVectors in {
15571582
(vti.Vector $rs1), $rs2, (NoX0 GPR:$vl), vti.SEW)>;
15581583
}
15591584
} // Predicates = [HasStdExtV]
1585+
1586+
//===----------------------------------------------------------------------===//
1587+
// 17.2. Floating-Point Scalar Move Instructions
1588+
//===----------------------------------------------------------------------===//
1589+
1590+
let Predicates = [HasStdExtV, HasStdExtF] in {
1591+
foreach fvti = AllFloatVectors in {
1592+
defvar instr = !cast<Instruction>("PseudoVFMV_F_S_" # fvti.LMul.MX);
1593+
def : Pat<(fvti.Scalar (int_riscv_vfmv_f_s (fvti.Vector fvti.RegClass:$rs2))),
1594+
// Floating point instructions with a scalar result will always
1595+
// generate the result in a register of class FPR32. When dealing
1596+
// with the f64 variant of a pattern we need to promote the FPR32
1597+
// subregister generated by the instruction to the FPR64 base
1598+
// register expected by the type in the pattern
1599+
!cond(!eq(!cast<string>(fvti.ScalarRegClass),
1600+
!cast<string>(FPR64)):
1601+
(SUBREG_TO_REG (i32 -1),
1602+
(instr $rs2, fvti.SEW), sub_32),
1603+
!eq(!cast<string>(fvti.ScalarRegClass),
1604+
!cast<string>(FPR16)):
1605+
(EXTRACT_SUBREG (instr $rs2, fvti.SEW), sub_16),
1606+
!eq(1, 1):
1607+
(instr $rs2, fvti.SEW))>;
1608+
1609+
def : Pat<(fvti.Vector (int_riscv_vfmv_s_f (fvti.Vector fvti.RegClass:$rs1),
1610+
(fvti.Scalar fvti.ScalarRegClass:$rs2), GPR:$vl)),
1611+
(!cast<Instruction>("PseudoVFMV_S_F_" # fvti.LMul.MX)
1612+
(fvti.Vector $rs1), ToFPR32<fvti.Scalar, fvti.ScalarRegClass, "rs2">.ret,
1613+
(NoX0 GPR:$vl), fvti.SEW)>;
1614+
}
1615+
} // Predicates = [HasStdExtV, HasStdExtF]
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=riscv64 -mattr=+d,+experimental-v,+experimental-zfh -target-abi lp64d -verify-machineinstrs < %s | FileCheck %s
3+
; RUN: llc -mtriple=riscv32 -mattr=+d,+experimental-v,+experimental-zfh -target-abi ilp32d -verify-machineinstrs < %s | FileCheck %s
4+
5+
declare half @llvm.riscv.vfmv.f.s.nxv1f16(<vscale x 1 x half>)
6+
7+
define half @intrinsic_vfmv.f.s_s_nxv1f16(<vscale x 1 x half> %0) nounwind {
8+
; CHECK-LABEL: intrinsic_vfmv.f.s_s_nxv1f16:
9+
; CHECK: # %bb.0: # %entry
10+
; CHECK-NEXT: vsetvli zero, zero, e16,mf4,ta,mu
11+
; CHECK-NEXT: vfmv.f.s fa0, v16
12+
; CHECK-NEXT: # kill: def $f10_h killed $f10_h killed $f10_f
13+
; CHECK-NEXT: ret
14+
entry:
15+
%a = call half @llvm.riscv.vfmv.f.s.nxv1f16(<vscale x 1 x half> %0)
16+
ret half %a
17+
}
18+
19+
declare half @llvm.riscv.vfmv.f.s.nxv2f16(<vscale x 2 x half>)
20+
21+
define half @intrinsic_vfmv.f.s_s_nxv2f16(<vscale x 2 x half> %0) nounwind {
22+
; CHECK-LABEL: intrinsic_vfmv.f.s_s_nxv2f16:
23+
; CHECK: # %bb.0: # %entry
24+
; CHECK-NEXT: vsetvli zero, zero, e16,mf2,ta,mu
25+
; CHECK-NEXT: vfmv.f.s fa0, v16
26+
; CHECK-NEXT: # kill: def $f10_h killed $f10_h killed $f10_f
27+
; CHECK-NEXT: ret
28+
entry:
29+
%a = call half @llvm.riscv.vfmv.f.s.nxv2f16(<vscale x 2 x half> %0)
30+
ret half %a
31+
}
32+
33+
declare half @llvm.riscv.vfmv.f.s.nxv4f16(<vscale x 4 x half>)
34+
35+
define half @intrinsic_vfmv.f.s_s_nxv4f16(<vscale x 4 x half> %0) nounwind {
36+
; CHECK-LABEL: intrinsic_vfmv.f.s_s_nxv4f16:
37+
; CHECK: # %bb.0: # %entry
38+
; CHECK-NEXT: vsetvli zero, zero, e16,m1,ta,mu
39+
; CHECK-NEXT: vfmv.f.s fa0, v16
40+
; CHECK-NEXT: # kill: def $f10_h killed $f10_h killed $f10_f
41+
; CHECK-NEXT: ret
42+
entry:
43+
%a = call half @llvm.riscv.vfmv.f.s.nxv4f16(<vscale x 4 x half> %0)
44+
ret half %a
45+
}
46+
47+
declare half @llvm.riscv.vfmv.f.s.nxv8f16(<vscale x 8 x half>)
48+
49+
define half @intrinsic_vfmv.f.s_s_nxv8f16(<vscale x 8 x half> %0) nounwind {
50+
; CHECK-LABEL: intrinsic_vfmv.f.s_s_nxv8f16:
51+
; CHECK: # %bb.0: # %entry
52+
; CHECK-NEXT: vsetvli zero, zero, e16,m2,ta,mu
53+
; CHECK-NEXT: vfmv.f.s fa0, v16
54+
; CHECK-NEXT: # kill: def $f10_h killed $f10_h killed $f10_f
55+
; CHECK-NEXT: ret
56+
entry:
57+
%a = call half @llvm.riscv.vfmv.f.s.nxv8f16(<vscale x 8 x half> %0)
58+
ret half %a
59+
}
60+
61+
declare half @llvm.riscv.vfmv.f.s.nxv16f16(<vscale x 16 x half>)
62+
63+
define half @intrinsic_vfmv.f.s_s_nxv16f16(<vscale x 16 x half> %0) nounwind {
64+
; CHECK-LABEL: intrinsic_vfmv.f.s_s_nxv16f16:
65+
; CHECK: # %bb.0: # %entry
66+
; CHECK-NEXT: vsetvli zero, zero, e16,m4,ta,mu
67+
; CHECK-NEXT: vfmv.f.s fa0, v16
68+
; CHECK-NEXT: # kill: def $f10_h killed $f10_h killed $f10_f
69+
; CHECK-NEXT: ret
70+
entry:
71+
%a = call half @llvm.riscv.vfmv.f.s.nxv16f16(<vscale x 16 x half> %0)
72+
ret half %a
73+
}
74+
75+
declare half @llvm.riscv.vfmv.f.s.nxv32f16(<vscale x 32 x half>)
76+
77+
define half @intrinsic_vfmv.f.s_s_nxv32f16(<vscale x 32 x half> %0) nounwind {
78+
; CHECK-LABEL: intrinsic_vfmv.f.s_s_nxv32f16:
79+
; CHECK: # %bb.0: # %entry
80+
; CHECK-NEXT: vsetvli zero, zero, e16,m8,ta,mu
81+
; CHECK-NEXT: vfmv.f.s fa0, v16
82+
; CHECK-NEXT: # kill: def $f10_h killed $f10_h killed $f10_f
83+
; CHECK-NEXT: ret
84+
entry:
85+
%a = call half @llvm.riscv.vfmv.f.s.nxv32f16(<vscale x 32 x half> %0)
86+
ret half %a
87+
}
88+
89+
declare float @llvm.riscv.vfmv.f.s.nxv1f32(<vscale x 1 x float>)
90+
91+
define float @intrinsic_vfmv.f.s_s_nxv1f32(<vscale x 1 x float> %0) nounwind {
92+
; CHECK-LABEL: intrinsic_vfmv.f.s_s_nxv1f32:
93+
; CHECK: # %bb.0: # %entry
94+
; CHECK-NEXT: vsetvli zero, zero, e32,mf2,ta,mu
95+
; CHECK-NEXT: vfmv.f.s fa0, v16
96+
; CHECK-NEXT: ret
97+
entry:
98+
%a = call float @llvm.riscv.vfmv.f.s.nxv1f32(<vscale x 1 x float> %0)
99+
ret float %a
100+
}
101+
102+
declare float @llvm.riscv.vfmv.f.s.nxv2f32(<vscale x 2 x float>)
103+
104+
define float @intrinsic_vfmv.f.s_s_nxv2f32(<vscale x 2 x float> %0) nounwind {
105+
; CHECK-LABEL: intrinsic_vfmv.f.s_s_nxv2f32:
106+
; CHECK: # %bb.0: # %entry
107+
; CHECK-NEXT: vsetvli zero, zero, e32,m1,ta,mu
108+
; CHECK-NEXT: vfmv.f.s fa0, v16
109+
; CHECK-NEXT: ret
110+
entry:
111+
%a = call float @llvm.riscv.vfmv.f.s.nxv2f32(<vscale x 2 x float> %0)
112+
ret float %a
113+
}
114+
115+
declare float @llvm.riscv.vfmv.f.s.nxv4f32(<vscale x 4 x float>)
116+
117+
define float @intrinsic_vfmv.f.s_s_nxv4f32(<vscale x 4 x float> %0) nounwind {
118+
; CHECK-LABEL: intrinsic_vfmv.f.s_s_nxv4f32:
119+
; CHECK: # %bb.0: # %entry
120+
; CHECK-NEXT: vsetvli zero, zero, e32,m2,ta,mu
121+
; CHECK-NEXT: vfmv.f.s fa0, v16
122+
; CHECK-NEXT: ret
123+
entry:
124+
%a = call float @llvm.riscv.vfmv.f.s.nxv4f32(<vscale x 4 x float> %0)
125+
ret float %a
126+
}
127+
128+
declare float @llvm.riscv.vfmv.f.s.nxv8f32(<vscale x 8 x float>)
129+
130+
define float @intrinsic_vfmv.f.s_s_nxv8f32(<vscale x 8 x float> %0) nounwind {
131+
; CHECK-LABEL: intrinsic_vfmv.f.s_s_nxv8f32:
132+
; CHECK: # %bb.0: # %entry
133+
; CHECK-NEXT: vsetvli zero, zero, e32,m4,ta,mu
134+
; CHECK-NEXT: vfmv.f.s fa0, v16
135+
; CHECK-NEXT: ret
136+
entry:
137+
%a = call float @llvm.riscv.vfmv.f.s.nxv8f32(<vscale x 8 x float> %0)
138+
ret float %a
139+
}
140+
141+
declare float @llvm.riscv.vfmv.f.s.nxv16f32(<vscale x 16 x float>)
142+
143+
define float @intrinsic_vfmv.f.s_s_nxv16f32(<vscale x 16 x float> %0) nounwind {
144+
; CHECK-LABEL: intrinsic_vfmv.f.s_s_nxv16f32:
145+
; CHECK: # %bb.0: # %entry
146+
; CHECK-NEXT: vsetvli zero, zero, e32,m8,ta,mu
147+
; CHECK-NEXT: vfmv.f.s fa0, v16
148+
; CHECK-NEXT: ret
149+
entry:
150+
%a = call float @llvm.riscv.vfmv.f.s.nxv16f32(<vscale x 16 x float> %0)
151+
ret float %a
152+
}
153+
154+
declare double @llvm.riscv.vfmv.f.s.nxv1f64(<vscale x 1 x double>)
155+
156+
define double @intrinsic_vfmv.f.s_s_nxv1f64(<vscale x 1 x double> %0) nounwind {
157+
; CHECK-LABEL: intrinsic_vfmv.f.s_s_nxv1f64:
158+
; CHECK: # %bb.0: # %entry
159+
; CHECK-NEXT: vsetvli zero, zero, e64,m1,ta,mu
160+
; CHECK-NEXT: vfmv.f.s fa0, v16
161+
; CHECK-NEXT: ret
162+
entry:
163+
%a = call double @llvm.riscv.vfmv.f.s.nxv1f64(<vscale x 1 x double> %0)
164+
ret double %a
165+
}
166+
167+
declare double @llvm.riscv.vfmv.f.s.nxv2f64(<vscale x 2 x double>)
168+
169+
define double @intrinsic_vfmv.f.s_s_nxv2f64(<vscale x 2 x double> %0) nounwind {
170+
; CHECK-LABEL: intrinsic_vfmv.f.s_s_nxv2f64:
171+
; CHECK: # %bb.0: # %entry
172+
; CHECK-NEXT: vsetvli zero, zero, e64,m2,ta,mu
173+
; CHECK-NEXT: vfmv.f.s fa0, v16
174+
; CHECK-NEXT: ret
175+
entry:
176+
%a = call double @llvm.riscv.vfmv.f.s.nxv2f64(<vscale x 2 x double> %0)
177+
ret double %a
178+
}
179+
180+
declare double @llvm.riscv.vfmv.f.s.nxv4f64(<vscale x 4 x double>)
181+
182+
define double @intrinsic_vfmv.f.s_s_nxv4f64(<vscale x 4 x double> %0) nounwind {
183+
; CHECK-LABEL: intrinsic_vfmv.f.s_s_nxv4f64:
184+
; CHECK: # %bb.0: # %entry
185+
; CHECK-NEXT: vsetvli zero, zero, e64,m4,ta,mu
186+
; CHECK-NEXT: vfmv.f.s fa0, v16
187+
; CHECK-NEXT: ret
188+
entry:
189+
%a = call double @llvm.riscv.vfmv.f.s.nxv4f64(<vscale x 4 x double> %0)
190+
ret double %a
191+
}
192+
193+
declare double @llvm.riscv.vfmv.f.s.nxv8f64(<vscale x 8 x double>)
194+
195+
define double @intrinsic_vfmv.f.s_s_nxv8f64(<vscale x 8 x double> %0) nounwind {
196+
; CHECK-LABEL: intrinsic_vfmv.f.s_s_nxv8f64:
197+
; CHECK: # %bb.0: # %entry
198+
; CHECK-NEXT: vsetvli zero, zero, e64,m8,ta,mu
199+
; CHECK-NEXT: vfmv.f.s fa0, v16
200+
; CHECK-NEXT: ret
201+
entry:
202+
%a = call double @llvm.riscv.vfmv.f.s.nxv8f64(<vscale x 8 x double> %0)
203+
ret double %a
204+
}

0 commit comments

Comments
 (0)