Skip to content

Commit 7648207

Browse files
committed
[RISCV][POC] Model frm control for vfadd
Depends on D152879. Specification PR: riscv-non-isa/rvv-intrinsic-doc#226 This patch adds variant of `vfadd` that models the rounding mode control. The added variant has suffix `_rm` appended to differentiate from the existing ones that does not alternate `frm` and uses whatever is inside. The value `7` is used to indicate no rounding mode change. Reusing the semantic from the rounding mode encoding for scalar floating-point instructions. Additional data member `HasFRMRoundModeOp` is added so we can append `_rm` suffix for the fadd variants that models rounding mode control. Additional data member `IsRVVFixedPoint` is added so we can define pseudo instructions with rounding mode operand and distinguish the instructions between fixed-point and floating-point. Reviewed By: craig.topper, kito-cheng Differential Revision: https://reviews.llvm.org/D152996
1 parent 503b3ab commit 7648207

35 files changed

+4758
-616
lines changed

clang/include/clang/Basic/riscv_vector.td

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,11 @@ multiclass RVVFloatingBinBuiltinSet
226226
[["vv", "v", "vvv"],
227227
["vf", "v", "vve"]]>;
228228

229+
multiclass RVVFloatingBinBuiltinSetRoundingMode
230+
: RVVOutOp1BuiltinSet<NAME, "xfd",
231+
[["vv", "v", "vvvu"],
232+
["vf", "v", "vveu"]]>;
233+
229234
multiclass RVVFloatingBinVFBuiltinSet
230235
: RVVOutOp1BuiltinSet<NAME, "xfd",
231236
[["vf", "v", "vve"]]>;
@@ -1856,10 +1861,72 @@ let ManualCodegen = [{
18561861
defm vnclipu : RVVUnsignedNShiftBuiltinSetRoundingMode;
18571862
defm vnclip : RVVSignedNShiftBuiltinSetRoundingMode;
18581863
}
1864+
}
18591865

18601866
// 14. Vector Floating-Point Instructions
1867+
let HeaderCode =
1868+
[{
1869+
enum __RISCV_FRM {
1870+
__RISCV_FRM_RNE = 0,
1871+
__RISCV_FRM_RTZ = 1,
1872+
__RISCV_FRM_RDN = 2,
1873+
__RISCV_FRM_RUP = 3,
1874+
__RISCV_FRM_RMM = 4,
1875+
};
1876+
}] in def frm_enum : RVVHeader;
1877+
1878+
let UnMaskedPolicyScheme = HasPassthruOperand in {
18611879
// 14.2. Vector Single-Width Floating-Point Add/Subtract Instructions
1862-
defm vfadd : RVVFloatingBinBuiltinSet;
1880+
let ManualCodegen = [{
1881+
{
1882+
// LLVM intrinsic
1883+
// Unmasked: (passthru, op0, op1, round_mode, vl)
1884+
// Masked: (passthru, vector_in, vector_in/scalar_in, mask, frm, vl, policy)
1885+
1886+
SmallVector<llvm::Value*, 7> Operands;
1887+
bool HasMaskedOff = !(
1888+
(IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
1889+
(!IsMasked && PolicyAttrs & RVV_VTA));
1890+
bool HasRoundModeOp = IsMasked ?
1891+
(HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5) :
1892+
(HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4);
1893+
1894+
unsigned Offset = IsMasked ?
1895+
(HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0);
1896+
1897+
if (!HasMaskedOff)
1898+
Operands.push_back(llvm::PoisonValue::get(ResultType));
1899+
else
1900+
Operands.push_back(Ops[IsMasked ? 1 : 0]);
1901+
1902+
Operands.push_back(Ops[Offset]); // op0
1903+
Operands.push_back(Ops[Offset + 1]); // op1
1904+
1905+
if (IsMasked)
1906+
Operands.push_back(Ops[0]); // mask
1907+
1908+
if (HasRoundModeOp) {
1909+
Operands.push_back(Ops[Offset + 2]); // frm
1910+
Operands.push_back(Ops[Offset + 3]); // vl
1911+
} else {
1912+
Operands.push_back(ConstantInt::get(Ops[Offset + 2]->getType(), 7)); // frm
1913+
Operands.push_back(Ops[Offset + 2]); // vl
1914+
}
1915+
1916+
if (IsMasked)
1917+
Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
1918+
1919+
IntrinsicTypes = {ResultType, Ops[Offset + 1]->getType(),
1920+
Operands.back()->getType()};
1921+
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
1922+
return Builder.CreateCall(F, Operands, "");
1923+
}
1924+
}] in {
1925+
let HasFRMRoundModeOp = true in {
1926+
defm vfadd : RVVFloatingBinBuiltinSetRoundingMode;
1927+
}
1928+
defm vfadd : RVVFloatingBinBuiltinSet;
1929+
}
18631930
defm vfsub : RVVFloatingBinBuiltinSet;
18641931
defm vfrsub : RVVFloatingBinVFBuiltinSet;
18651932

clang/include/clang/Basic/riscv_vector_common.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,10 @@ class RVVBuiltin<string suffix, string prototype, string type_range,
234234

235235
// Set to true if the builtin is associated with tuple types.
236236
bit IsTuple = false;
237+
238+
// Set to true if the builtin has a parameter that models floating-point
239+
// rounding mode control
240+
bit HasFRMRoundModeOp = false;
237241
}
238242

239243
// This is the code emitted in the header.

clang/include/clang/Support/RISCVVIntrinsicUtils.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ class RVVIntrinsic {
387387
std::vector<int64_t> IntrinsicTypes;
388388
unsigned NF = 1;
389389
Policy PolicyAttrs;
390+
bool HasFRMRoundModeOp;
390391

391392
public:
392393
RVVIntrinsic(llvm::StringRef Name, llvm::StringRef Suffix,
@@ -397,7 +398,7 @@ class RVVIntrinsic {
397398
const RVVTypes &Types,
398399
const std::vector<int64_t> &IntrinsicTypes,
399400
const std::vector<llvm::StringRef> &RequiredFeatures,
400-
unsigned NF, Policy PolicyAttrs);
401+
unsigned NF, Policy PolicyAttrs, bool HasFRMRoundModeOp);
401402
~RVVIntrinsic() = default;
402403

403404
RVVTypePtr getOutputType() const { return OutputType; }
@@ -467,7 +468,7 @@ class RVVIntrinsic {
467468
static void updateNamesAndPolicy(bool IsMasked, bool HasPolicy,
468469
std::string &Name, std::string &BuiltinName,
469470
std::string &OverloadedName,
470-
Policy &PolicyAttrs);
471+
Policy &PolicyAttrs, bool HasFRMRoundModeOp);
471472
};
472473

473474
// RVVRequire should be sync'ed with target features, but only
@@ -526,6 +527,7 @@ struct RVVIntrinsicRecord {
526527
bool HasMaskedOffOperand : 1;
527528
bool HasTailPolicy : 1;
528529
bool HasMaskPolicy : 1;
530+
bool HasFRMRoundModeOp : 1;
529531
bool IsTuple : 1;
530532
uint8_t UnMaskedPolicyScheme : 2;
531533
uint8_t MaskedPolicyScheme : 2;

clang/lib/Sema/SemaChecking.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4808,6 +4808,21 @@ bool Sema::CheckRISCVBuiltinFunctionCall(const TargetInfo &TI,
48084808
case RISCVVector::BI__builtin_rvv_vnclipu_wv_tumu:
48094809
case RISCVVector::BI__builtin_rvv_vnclipu_wx_tumu:
48104810
return SemaBuiltinConstantArgRange(TheCall, 4, 0, 3);
4811+
case RISCVVector::BI__builtin_rvv_vfadd_vv_rm:
4812+
case RISCVVector::BI__builtin_rvv_vfadd_vf_rm:
4813+
return SemaBuiltinConstantArgRange(TheCall, 2, 0, 4);
4814+
case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tu:
4815+
case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tu:
4816+
case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tama:
4817+
case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tama:
4818+
return SemaBuiltinConstantArgRange(TheCall, 3, 0, 4);
4819+
case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tum:
4820+
case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tum:
4821+
case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_tumu:
4822+
case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_tumu:
4823+
case RISCVVector::BI__builtin_rvv_vfadd_vv_rm_mu:
4824+
case RISCVVector::BI__builtin_rvv_vfadd_vf_rm_mu:
4825+
return SemaBuiltinConstantArgRange(TheCall, 4, 0, 4);
48114826
case RISCV::BI__builtin_riscv_ntl_load:
48124827
case RISCV::BI__builtin_riscv_ntl_store:
48134828
DeclRefExpr *DRE =

clang/lib/Sema/SemaRISCVVectorLookup.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,8 @@ void RISCVIntrinsicManagerImpl::InitRVVIntrinsic(
362362
std::string BuiltinName = "__builtin_rvv_" + std::string(Record.Name);
363363

364364
RVVIntrinsic::updateNamesAndPolicy(IsMasked, HasPolicy, Name, BuiltinName,
365-
OverloadedName, PolicyAttrs);
365+
OverloadedName, PolicyAttrs,
366+
Record.HasFRMRoundModeOp);
366367

367368
// Put into IntrinsicList.
368369
size_t Index = IntrinsicList.size();

clang/lib/Support/RISCVVIntrinsicUtils.cpp

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -875,20 +875,19 @@ std::optional<RVVTypePtr> RVVTypeCache::computeType(BasicType BT, int Log2LMUL,
875875
//===----------------------------------------------------------------------===//
876876
// RVVIntrinsic implementation
877877
//===----------------------------------------------------------------------===//
878-
RVVIntrinsic::RVVIntrinsic(StringRef NewName, StringRef Suffix,
879-
StringRef NewOverloadedName,
880-
StringRef OverloadedSuffix, StringRef IRName,
881-
bool IsMasked, bool HasMaskedOffOperand, bool HasVL,
882-
PolicyScheme Scheme, bool SupportOverloading,
883-
bool HasBuiltinAlias, StringRef ManualCodegen,
884-
const RVVTypes &OutInTypes,
885-
const std::vector<int64_t> &NewIntrinsicTypes,
886-
const std::vector<StringRef> &RequiredFeatures,
887-
unsigned NF, Policy NewPolicyAttrs)
878+
RVVIntrinsic::RVVIntrinsic(
879+
StringRef NewName, StringRef Suffix, StringRef NewOverloadedName,
880+
StringRef OverloadedSuffix, StringRef IRName, bool IsMasked,
881+
bool HasMaskedOffOperand, bool HasVL, PolicyScheme Scheme,
882+
bool SupportOverloading, bool HasBuiltinAlias, StringRef ManualCodegen,
883+
const RVVTypes &OutInTypes, const std::vector<int64_t> &NewIntrinsicTypes,
884+
const std::vector<StringRef> &RequiredFeatures, unsigned NF,
885+
Policy NewPolicyAttrs, bool HasFRMRoundModeOp)
888886
: IRName(IRName), IsMasked(IsMasked),
889887
HasMaskedOffOperand(HasMaskedOffOperand), HasVL(HasVL), Scheme(Scheme),
890888
SupportOverloading(SupportOverloading), HasBuiltinAlias(HasBuiltinAlias),
891-
ManualCodegen(ManualCodegen.str()), NF(NF), PolicyAttrs(NewPolicyAttrs) {
889+
ManualCodegen(ManualCodegen.str()), NF(NF), PolicyAttrs(NewPolicyAttrs),
890+
HasFRMRoundModeOp(HasFRMRoundModeOp) {
892891

893892
// Init BuiltinName, Name and OverloadedName
894893
BuiltinName = NewName.str();
@@ -903,7 +902,7 @@ RVVIntrinsic::RVVIntrinsic(StringRef NewName, StringRef Suffix,
903902
OverloadedName += "_" + OverloadedSuffix.str();
904903

905904
updateNamesAndPolicy(IsMasked, hasPolicy(), Name, BuiltinName, OverloadedName,
906-
PolicyAttrs);
905+
PolicyAttrs, HasFRMRoundModeOp);
907906

908907
// Init OutputType and InputTypes
909908
OutputType = OutInTypes[0];
@@ -1045,11 +1044,9 @@ RVVIntrinsic::getSupportedMaskedPolicies(bool HasTailPolicy,
10451044
"and mask policy");
10461045
}
10471046

1048-
void RVVIntrinsic::updateNamesAndPolicy(bool IsMasked, bool HasPolicy,
1049-
std::string &Name,
1050-
std::string &BuiltinName,
1051-
std::string &OverloadedName,
1052-
Policy &PolicyAttrs) {
1047+
void RVVIntrinsic::updateNamesAndPolicy(
1048+
bool IsMasked, bool HasPolicy, std::string &Name, std::string &BuiltinName,
1049+
std::string &OverloadedName, Policy &PolicyAttrs, bool HasFRMRoundModeOp) {
10531050

10541051
auto appendPolicySuffix = [&](const std::string &suffix) {
10551052
Name += suffix;
@@ -1062,6 +1059,11 @@ void RVVIntrinsic::updateNamesAndPolicy(bool IsMasked, bool HasPolicy,
10621059
Name = "__riscv_" + Name;
10631060
OverloadedName = "__riscv_" + OverloadedName;
10641061

1062+
if (HasFRMRoundModeOp) {
1063+
Name += "_rm";
1064+
BuiltinName += "_rm";
1065+
}
1066+
10651067
if (IsMasked) {
10661068
if (PolicyAttrs.isTUMUPolicy())
10671069
appendPolicySuffix("_tumu");
@@ -1131,6 +1133,7 @@ raw_ostream &operator<<(raw_ostream &OS, const RVVIntrinsicRecord &Record) {
11311133
OS << (int)Record.HasMaskedOffOperand << ",";
11321134
OS << (int)Record.HasTailPolicy << ",";
11331135
OS << (int)Record.HasMaskPolicy << ",";
1136+
OS << (int)Record.HasFRMRoundModeOp << ",";
11341137
OS << (int)Record.IsTuple << ",";
11351138
OS << (int)Record.UnMaskedPolicyScheme << ",";
11361139
OS << (int)Record.MaskedPolicyScheme << ",";

0 commit comments

Comments
 (0)