Skip to content

Commit daa224a

Browse files
committed
[RISCV] Support Inline ASM for the bf16 type.
This patch makes the RISCV-V asm constraint `f` recognize the bfloat type.
1 parent 698058f commit daa224a

File tree

2 files changed

+92
-1
lines changed

2 files changed

+92
-1
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20155,7 +20155,8 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2015520155
return std::make_pair(0U, &RISCV::GPRPairRegClass);
2015620156
return std::make_pair(0U, &RISCV::GPRNoX0RegClass);
2015720157
case 'f':
20158-
if (Subtarget.hasStdExtZfhmin() && VT == MVT::f16)
20158+
if ((Subtarget.hasStdExtZfhmin() && VT == MVT::f16) ||
20159+
(Subtarget.hasStdExtZfbfmin() && VT == MVT::bf16))
2015920160
return std::make_pair(0U, &RISCV::FPR16RegClass);
2016020161
if (Subtarget.hasStdExtF() && VT == MVT::f32)
2016120162
return std::make_pair(0U, &RISCV::FPR32RegClass);
@@ -20273,6 +20274,11 @@ RISCVTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
2027320274
unsigned HReg = RISCV::F0_H + RegNo;
2027420275
return std::make_pair(HReg, &RISCV::FPR16RegClass);
2027520276
}
20277+
if (Subtarget.hasStdExtZfbfmin() && VT == MVT::bf16){
20278+
unsigned RegNo = FReg - RISCV::F0_F;
20279+
unsigned HReg = RISCV::F0_H + RegNo;
20280+
return std::make_pair(HReg, &RISCV::FPR16RegClass);
20281+
}
2027620282
}
2027720283
}
2027820284

@@ -20949,6 +20955,14 @@ bool RISCVTargetLowering::splitValueIntoRegisterParts(
2094920955
return true;
2095020956
}
2095120957

20958+
// Since the inline asm only use the first type in the RegisterClass, the bf16
20959+
// inline asm would choose the f16 from FPR16RegClass for doing the copy, and
20960+
// we correct the behavior here to avoid generating wrong SelectionDAG.
20961+
if (ValueVT == MVT::bf16 && PartVT == MVT::f16){
20962+
Parts[0] = Val;
20963+
return true;
20964+
}
20965+
2095220966
if (ValueVT.isScalableVector() && PartVT.isScalableVector()) {
2095320967
LLVMContext &Context = *DAG.getContext();
2095420968
EVT ValueEltVT = ValueVT.getVectorElementType();
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=riscv32 -mattr=+f,+experimental-zfbfmin -target-abi=ilp32 -verify-machineinstrs < %s \
3+
; RUN: | FileCheck -check-prefix=RV32F %s
4+
; RUN: llc -mtriple=riscv64 -mattr=+f,+experimental-zfbfmin -target-abi=lp64 -verify-machineinstrs < %s \
5+
; RUN: | FileCheck -check-prefix=RV64F %s
6+
; RUN: llc -mtriple=riscv32 -mattr=+d,+experimental-zfbfmin -target-abi=ilp32 -verify-machineinstrs < %s \
7+
; RUN: | FileCheck -check-prefix=RV32F %s
8+
; RUN: llc -mtriple=riscv64 -mattr=+d,+experimental-zfbfmin -target-abi=lp64 -verify-machineinstrs < %s \
9+
; RUN: | FileCheck -check-prefix=RV64F %s
10+
11+
@gf = external global float
12+
13+
define float @constraint_f_float(bfloat %a) nounwind {
14+
; RV32F-LABEL: constraint_f_float:
15+
; RV32F: # %bb.0:
16+
; RV32F-NEXT: fmv.h.x fa5, a0
17+
; RV32F-NEXT: #APP
18+
; RV32F-NEXT: fcvt.s.bf16 fa5, fa5
19+
; RV32F-NEXT: #NO_APP
20+
; RV32F-NEXT: fmv.x.w a0, fa5
21+
; RV32F-NEXT: ret
22+
;
23+
; RV64F-LABEL: constraint_f_float:
24+
; RV64F: # %bb.0:
25+
; RV64F-NEXT: fmv.h.x fa5, a0
26+
; RV64F-NEXT: #APP
27+
; RV64F-NEXT: fcvt.s.bf16 fa5, fa5
28+
; RV64F-NEXT: #NO_APP
29+
; RV64F-NEXT: fmv.x.w a0, fa5
30+
; RV64F-NEXT: ret
31+
%1 = load float, float* @gf
32+
%2 = tail call float asm "fcvt.s.bf16 $0, $1", "=f,f"(bfloat %a)
33+
ret float %2
34+
}
35+
36+
define float @constraint_f_float_abi_name(bfloat %a) nounwind {
37+
; RV32F-LABEL: constraint_f_float_abi_name:
38+
; RV32F: # %bb.0:
39+
; RV32F-NEXT: fmv.h.x fa0, a0
40+
; RV32F-NEXT: #APP
41+
; RV32F-NEXT: fcvt.s.bf16 ft0, fa0
42+
; RV32F-NEXT: #NO_APP
43+
; RV32F-NEXT: fmv.x.w a0, ft0
44+
; RV32F-NEXT: ret
45+
;
46+
; RV64F-LABEL: constraint_f_float_abi_name:
47+
; RV64F: # %bb.0:
48+
; RV64F-NEXT: fmv.h.x fa0, a0
49+
; RV64F-NEXT: #APP
50+
; RV64F-NEXT: fcvt.s.bf16 ft0, fa0
51+
; RV64F-NEXT: #NO_APP
52+
; RV64F-NEXT: fmv.x.w a0, ft0
53+
; RV64F-NEXT: ret
54+
%1 = load float, float* @gf
55+
%2 = tail call float asm "fcvt.s.bf16 $0, $1", "={ft0},{fa0}"(bfloat %a)
56+
ret float %2
57+
}
58+
59+
define bfloat @constraint_gpr(bfloat %x) {
60+
; RV32F-LABEL: constraint_gpr:
61+
; RV32F: # %bb.0:
62+
; RV32F-NEXT: .cfi_def_cfa_offset 0
63+
; RV32F-NEXT: #APP
64+
; RV32F-NEXT: mv a0, a0
65+
; RV32F-NEXT: #NO_APP
66+
; RV32F-NEXT: ret
67+
;
68+
; RV64F-LABEL: constraint_gpr:
69+
; RV64F: # %bb.0:
70+
; RV64F-NEXT: .cfi_def_cfa_offset 0
71+
; RV64F-NEXT: #APP
72+
; RV64F-NEXT: mv a0, a0
73+
; RV64F-NEXT: #NO_APP
74+
; RV64F-NEXT: ret
75+
%1 = tail call bfloat asm sideeffect alignstack "mv $0, $1", "={x10},{x10}"(bfloat %x)
76+
ret bfloat %1
77+
}

0 commit comments

Comments
 (0)