Skip to content

[RISCV] Support XSfmm C intrinsics #143070

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 170 additions & 0 deletions clang/include/clang/Basic/riscv_sifive_vector.td
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

include "riscv_vector_common.td"

class IsFloat<string type> {
bit val = !or(!eq(type, "x"), !eq(type, "f"), !eq(type, "d"), !eq(type, "y"));
}

//===----------------------------------------------------------------------===//
// Instruction definitions
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -198,3 +202,169 @@ let ManualCodegen = [{
defm sf_vfnrclip_xu_f_qf : RVVVFNRCLIPBuiltinSet<"Uv", "UvFqf", "c">;
}
}

multiclass RVVSFTileLoadStoreBuiltinSet<list<string> types,
list<string> RequiredFeatures = []> {
let OverloadedName = NAME,
Name = NAME,
IRName = NAME,
Log2LMUL = [0],
HasMasked = false,
ManualCodegen = [{IntrinsicTypes = {Ops.back()->getType()};}] in
foreach type = types in {
let RequiredFeatures = !listconcat(RequiredFeatures,
!cond(!eq(type, "x"): ["Zvfhmin"],
!eq(type, "y"): ["Zvfbfmin"],
true: []<string>)) in {
def : RVVBuiltin<"e", "0zPCe", type>;
if !not(IsFloat<type>.val) then
def : RVVBuiltin<"Ue", "0zPCUe", type>;
}
}
}

multiclass RVVSFTileMoveBuiltinSet<list<list<string>> suffixes_prototypes,
list<int> intrinsic_types,
string type,
list<string> RequiredFeatures = []> {
foreach sp = suffixes_prototypes in
let RequiredFeatures = !listconcat(RequiredFeatures,
!cond(!eq(type, "x"): ["Zvfhmin"],
!eq(type, "y"): ["Zvfbfmin"],
true: []<string>)),
SupportOverloading = false,
HasMasked = false,
Name = NAME,
IRName = NAME,
HasVL = true,
Log2LMUL = [3],
IntrinsicTypes = intrinsic_types in
def : RVVBuiltin<sp[0], sp[1], type>;
}

multiclass RVVSFTileMoveVTBuiltinSet<list<string> RequiredFeatures = []> {
foreach type = ["c", "s", "i", "l"] in
defm NAME :
RVVSFTileMoveBuiltinSet<[["v", "vz"], ["Uv", "Uvz"]], [-1], type,
RequiredFeatures>;
foreach type = ["x", "y", "f", "d"] in
defm NAME :
RVVSFTileMoveBuiltinSet<[["v", "vz"]], [-1], type, RequiredFeatures>;
}

multiclass RVVSFTileMoveTVBuiltinSet<list<string> RequiredFeatures = []> {
let SupportOverloading = true, OverloadedName = NAME in {
foreach type = ["c", "s", "i", "l"] in
defm NAME :
RVVSFTileMoveBuiltinSet<[["v", "0zv"], ["Uv", "0zUv"]], [1], type,
RequiredFeatures>;
foreach type = ["x", "y", "f", "d"] in
defm NAME :
RVVSFTileMoveBuiltinSet<[["v", "0zv"]], [1], type, RequiredFeatures>;
}
}

multiclass RVVOp0Op1Op2BuiltinSet<string intrinsic_name, string type_range,
list<list<string>> suffixes_prototypes>
: RVVBuiltinSet<intrinsic_name, type_range, suffixes_prototypes, [0, 1, 2]>;

multiclass RVVSFMatMulBuiltinSet<string prototype, string suffix,
string type_range, list<int> widens> {
foreach widen = widens in
let OverloadedName = NAME,
TWiden = widen,
HasVL = false,
Log2LMUL = [3],
HasMasked = false in
defm NAME : RVVOp0Op1Op2BuiltinSet<NAME, type_range,
[[!strconcat("w", !cast<string>(widen)), suffix, prototype]]>;
}

multiclass RVVSFMatMulFloatBuiltinSet<string name, string prototype, string suffix,
list<string> type_range, int widen> {
// Currently the XSfmm spec doesn't support w8.
foreach type = type_range in
let OverloadedName = name # !strconcat("_w", !cast<string>(widen)),
TWiden = widen,
HasVL = false,
Log2LMUL = [3],
Name = name # "_" # !strconcat("w", !cast<string>(widen)),
HasMasked = false in
defm : RVVOp0Op1BuiltinSet<name, type, [["", suffix, prototype]]>;
}

multiclass RVVSFVTZeroBuiltinSet {
let SupportOverloading = false,
HasVL = false,
HasMasked = false,
Name = NAME,
IRName = NAME,
Log2LMUL = [0] in
defm : RVVOp0BuiltinSet<NAME, "i", [["", "", "0Kzzzzz"]]>;
}

multiclass RVVSFVTDiscardBuiltinSet {
let SupportOverloading = false,
HasVL = false,
HasMasked = false,
Name = NAME,
IRName = NAME,
Log2LMUL = [0] in
defm : RVVBuiltinSet<NAME, "i", [["", "", "0"]], []>;
}

let RequiredFeatures = ["Xsfmmbase"] in {
let SupportOverloading = false,
HasVL = false,
HasMasked = false,
Log2LMUL = [0],
ManualCodegen = [{IntrinsicTypes = {ResultType};}] in // Set XLEN type
{
// let HasBuiltinAlias = false in
def sf_vsettnt : RVVBuiltin<"", "zzKzKz", "i">;
def sf_vsettm : RVVBuiltin<"", "zzKzKz", "i">;
let IRName = "sf_vsettnt" in
def sf_vsettn : RVVBuiltin<"", "zzKzKz", "i">;
def sf_vsettk : RVVBuiltin<"", "zzKzKz", "i">;
}
defm sf_vtzero_t : RVVSFVTZeroBuiltinSet;
defm sf_vtdiscard : RVVSFVTDiscardBuiltinSet;
}

defm sf_vtmv_v_t : RVVSFTileMoveVTBuiltinSet<["Xsfmmbase"]>;
defm sf_vtmv_t_v : RVVSFTileMoveTVBuiltinSet<["Xsfmmbase"]>;

defm sf_vlte8 : RVVSFTileLoadStoreBuiltinSet<["c"], ["Xsfmmbase"]>;
defm sf_vlte16 : RVVSFTileLoadStoreBuiltinSet<["s", "x", "y"], ["Xsfmmbase"]>;
defm sf_vlte32 : RVVSFTileLoadStoreBuiltinSet<["i", "f"], ["Xsfmmbase"]>;
defm sf_vlte64 : RVVSFTileLoadStoreBuiltinSet<["l", "d"], ["Xsfmmbase"]>;

defm sf_vste8 : RVVSFTileLoadStoreBuiltinSet<["c"], ["Xsfmmbase"]>;
defm sf_vste16 : RVVSFTileLoadStoreBuiltinSet<["s", "x", "y"], ["Xsfmmbase"]>;
defm sf_vste32 : RVVSFTileLoadStoreBuiltinSet<["i", "f"], ["Xsfmmbase"]>;
defm sf_vste64 : RVVSFTileLoadStoreBuiltinSet<["l", "d"], ["Xsfmmbase"]>;

let RequiredFeatures = ["Xsfmm32a8i"] in {
defm sf_mm_u_u : RVVSFMatMulBuiltinSet<"0KzUvUvzzz", "UvUv", "c", [4]>;
defm sf_mm_s_u : RVVSFMatMulBuiltinSet<"0KzvUvzzz", "vUv", "c", [4]>;
defm sf_mm_u_s : RVVSFMatMulBuiltinSet<"0KzUvvzzz", "Uvv", "c", [4]>;
defm sf_mm_s_s : RVVSFMatMulBuiltinSet<"0Kzvvzzz", "vv", "c", [4]>;

}

let RequiredFeatures = ["Xsfmm32a16f"] in
defm : RVVSFMatMulFloatBuiltinSet<"sf_mm_f_f", "0Kzvvzzz", "v", ["x", "y"], 2>;

let RequiredFeatures = ["Xsfmm32a32f"] in
defm : RVVSFMatMulFloatBuiltinSet<"sf_mm_f_f", "0Kzvvzzz", "v", ["f"], 1>;

let RequiredFeatures = ["Xsfmm32a8f"] in
foreach e1 = [5, 4] in
foreach e2 = [5, 4] in
let OverloadedName = "sf_mm_e" # e1 # "m" # !sub(7, e1) # "_e" # e2 # "m" # !sub(7, e2) in
defm : RVVSFMatMulFloatBuiltinSet<
"sf_mm_e" # e1 # "m" # !sub(7, e1) # "_e" # e2 # "m" # !sub(7, e2),
"0KzUvUvzzz", "UvUv", ["c"], 4>;

let RequiredFeatures = ["Xsfmm64a64f"] in
defm : RVVSFMatMulFloatBuiltinSet<"sf_mm_f_f", "0Kzvvzzz", "v", ["d"], 1>;
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/riscv_vector_common.td
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ class RVVBuiltin<string suffix, string prototype, string type_range,
// Set to true if the builtin has a parameter that models floating-point
// rounding mode control
bit HasFRMRoundModeOp = false;

// TWiden for XSfmm.
int TWiden = 0;
}

// This is the code emitted in the header.
Expand Down
12 changes: 10 additions & 2 deletions clang/include/clang/Support/RISCVVIntrinsicUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ class RVVIntrinsic {
std::vector<int64_t> IntrinsicTypes;
unsigned NF = 1;
Policy PolicyAttrs;
unsigned TWiden = 0;

public:
RVVIntrinsic(llvm::StringRef Name, llvm::StringRef Suffix,
Expand All @@ -411,8 +412,8 @@ class RVVIntrinsic {
bool HasVL, PolicyScheme Scheme, bool SupportOverloading,
bool HasBuiltinAlias, llvm::StringRef ManualCodegen,
const RVVTypes &Types,
const std::vector<int64_t> &IntrinsicTypes,
unsigned NF, Policy PolicyAttrs, bool HasFRMRoundModeOp);
const std::vector<int64_t> &IntrinsicTypes, unsigned NF,
Policy PolicyAttrs, bool HasFRMRoundModeOp, unsigned TWiden);
~RVVIntrinsic() = default;

RVVTypePtr getOutputType() const { return OutputType; }
Expand All @@ -436,6 +437,7 @@ class RVVIntrinsic {
llvm::StringRef getManualCodegen() const { return ManualCodegen; }
PolicyScheme getPolicyScheme() const { return Scheme; }
unsigned getNF() const { return NF; }
unsigned getTWiden() const { return TWiden; }
const std::vector<int64_t> &getIntrinsicTypes() const {
return IntrinsicTypes;
}
Expand Down Expand Up @@ -508,6 +510,12 @@ enum RVVRequire {
RVV_REQ_Zvfbfwma,
RVV_REQ_Zvfbfmin,
RVV_REQ_Zvfh,
RVV_REQ_Xsfmmbase,
RVV_REQ_Xsfmm32a8f,
RVV_REQ_Xsfmm32a16f,
RVV_REQ_Xsfmm32a32f,
RVV_REQ_Xsfmm64a64f,
RVV_REQ_Xsfmm32a8i,
RVV_REQ_Experimental,
RVV_REQ_NUM,
};
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CodeGen/TargetBuiltins/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
bool IsMasked = false;
// This is used by segment load/store to determine it's llvm type.
unsigned SegInstSEW = 8;
// This is used by XSfmm.
unsigned TWiden = 0;

// Required for overloaded intrinsics.
llvm::SmallVector<llvm::Type *, 2> IntrinsicTypes;
Expand Down
56 changes: 56 additions & 0 deletions clang/lib/Headers/sifive_vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,60 @@
#endif
#endif

#define __riscv_sf_vsettnt_e8w1(atn) __riscv_sf_vsettnt(atn, 0, 1);
#define __riscv_sf_vsettnt_e8w2(atn) __riscv_sf_vsettnt(atn, 0, 2);
#define __riscv_sf_vsettnt_e8w4(atn) __riscv_sf_vsettnt(atn, 0, 3);
#define __riscv_sf_vsettnt_e16w1(atn) __riscv_sf_vsettnt(atn, 1, 1);
#define __riscv_sf_vsettnt_e16w2(atn) __riscv_sf_vsettnt(atn, 1, 2);
#define __riscv_sf_vsettnt_e16w4(atn) __riscv_sf_vsettnt(atn, 1, 3);
#define __riscv_sf_vsettnt_e32w1(atn) __riscv_sf_vsettnt(atn, 2, 1);
#define __riscv_sf_vsettnt_e32w2(atn) __riscv_sf_vsettnt(atn, 2, 2);
#define __riscv_sf_vsettm_e8w1(atm) __riscv_sf_vsettm(atm, 0, 1);
#define __riscv_sf_vsettm_e8w2(atm) __riscv_sf_vsettm(atm, 0, 2);
#define __riscv_sf_vsettm_e8w4(atm) __riscv_sf_vsettm(atm, 0, 3);
#define __riscv_sf_vsettm_e16w1(atm) __riscv_sf_vsettm(atm, 1, 1);
#define __riscv_sf_vsettm_e16w2(atm) __riscv_sf_vsettm(atm, 1, 2);
#define __riscv_sf_vsettm_e16w4(atm) __riscv_sf_vsettm(atm, 1, 3);
#define __riscv_sf_vsettm_e32w1(atm) __riscv_sf_vsettm(atm, 2, 1);
#define __riscv_sf_vsettm_e32w2(atm) __riscv_sf_vsettm(atm, 2, 2);
#define __riscv_sf_vsettn_e8w1(atn) __riscv_sf_vsettn(atn, 0, 1);
#define __riscv_sf_vsettn_e8w2(atn) __riscv_sf_vsettn(atn, 0, 2);
#define __riscv_sf_vsettn_e8w4(atn) __riscv_sf_vsettn(atn, 0, 3);
#define __riscv_sf_vsettn_e16w1(atn) __riscv_sf_vsettn(atn, 1, 1);
#define __riscv_sf_vsettn_e16w2(atn) __riscv_sf_vsettn(atn, 1, 2);
#define __riscv_sf_vsettn_e16w4(atn) __riscv_sf_vsettn(atn, 1, 3);
#define __riscv_sf_vsettn_e32w1(atn) __riscv_sf_vsettn(atn, 2, 1);
#define __riscv_sf_vsettn_e32w2(atn) __riscv_sf_vsettn(atn, 2, 2);
#define __riscv_sf_vsettk_e8w1(atk) __riscv_sf_vsettk(atk, 0, 1);
#define __riscv_sf_vsettk_e8w2(atk) __riscv_sf_vsettk(atk, 0, 2);
#define __riscv_sf_vsettk_e8w4(atk) __riscv_sf_vsettk(atk, 0, 3);
#define __riscv_sf_vsettk_e16w1(atk) __riscv_sf_vsettk(atk, 1, 1);
#define __riscv_sf_vsettk_e16w2(atk) __riscv_sf_vsettk(atk, 1, 2);
#define __riscv_sf_vsettk_e16w4(atk) __riscv_sf_vsettk(atk, 1, 3);
#define __riscv_sf_vsettk_e32w1(atk) __riscv_sf_vsettk(atk, 2, 1);
#define __riscv_sf_vsettk_e32w2(atk) __riscv_sf_vsettk(atk, 2, 2);
#define __riscv_sf_vtzero_t_e8w1(tile, atm, atn) \
__riscv_sf_vtzero_t(tile, atm, atn, 3, 1);
#define __riscv_sf_vtzero_t_e8w2(tile, atm, atn) \
__riscv_sf_vtzero_t(tile, atm, atn, 3, 2);
#define __riscv_sf_vtzero_t_e8w4(tile, atm, atn) \
__riscv_sf_vtzero_t(tile, atm, atn, 3, 4);
#define __riscv_sf_vtzero_t_e16w1(tile, atm, atn) \
__riscv_sf_vtzero_t(tile, atm, atn, 4, 1);
#define __riscv_sf_vtzero_t_e16w2(tile, atm, atn) \
__riscv_sf_vtzero_t(tile, atm, atn, 4, 2);
#define __riscv_sf_vtzero_t_e16w4(tile, atm, atn) \
__riscv_sf_vtzero_t(tile, atm, atn, 4, 4);
#define __riscv_sf_vtzero_t_e32w1(tile, atm, atn) \
__riscv_sf_vtzero_t(tile, atm, atn, 5, 1);
#define __riscv_sf_vtzero_t_e32w2(tile, atm, atn) \
__riscv_sf_vtzero_t(tile, atm, atn, 5, 2);
#if __riscv_v_elen >= 64
#define __riscv_sf_vsettnt_e64w1(atn) __riscv_sf_vsettnt(atn, 3, 1);
#define __riscv_sf_vsettm_e64w1(atm) __riscv_sf_vsettm(atm, 3, 1);
#define __riscv_sf_vsettn_e64w1(atn) __riscv_sf_vsettn(atn, 3, 1);
#define __riscv_sf_vsettk_e64w1(atk) __riscv_sf_vsettk(atk, 3, 1);
#define __riscv_sf_vtzero_t_e64w1(tile, atm, atn) \
__riscv_sf_vtzero_t(tile, atm, atn, 6, 1);
#endif
#endif //_SIFIVE_VECTOR_H_
50 changes: 50 additions & 0 deletions clang/lib/Sema/SemaRISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,12 @@ void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics(
{"zvfbfwma", RVV_REQ_Zvfbfwma},
{"zvfbfmin", RVV_REQ_Zvfbfmin},
{"zvfh", RVV_REQ_Zvfh},
{"xsfmmbase", RVV_REQ_Xsfmmbase},
{"xsfmm32a8f", RVV_REQ_Xsfmm32a8f},
{"xsfmm32a16f", RVV_REQ_Xsfmm32a16f},
{"xsfmm32a32f", RVV_REQ_Xsfmm32a32f},
{"xsfmm64a64f", RVV_REQ_Xsfmm64a64f},
{"xsfmm32a8i", RVV_REQ_Xsfmm32a8i},
{"experimental", RVV_REQ_Experimental}};

// Construction of RVVIntrinsicRecords need to sync with createRVVIntrinsics
Expand Down Expand Up @@ -679,6 +685,50 @@ bool SemaRISCV::CheckBuiltinFunctionCall(const TargetInfo &TI,
return CheckVSetVL(1, 2);
case RISCVVector::BI__builtin_rvv_vsetvlimax:
return CheckVSetVL(0, 1);
case RISCVVector::BI__builtin_rvv_sf_vsettnt:
case RISCVVector::BI__builtin_rvv_sf_vsettm:
case RISCVVector::BI__builtin_rvv_sf_vsettn:
case RISCVVector::BI__builtin_rvv_sf_vsettk:
return SemaRef.BuiltinConstantArgRange(TheCall, 1, 0, 3) ||
SemaRef.BuiltinConstantArgRange(TheCall, 2, 1, 3);
case RISCVVector::BI__builtin_rvv_sf_mm_f_f_w1:
case RISCVVector::BI__builtin_rvv_sf_mm_f_f_w2:
case RISCVVector::BI__builtin_rvv_sf_mm_e5m2_e4m3_w4:
case RISCVVector::BI__builtin_rvv_sf_mm_e5m2_e5m2_w4:
case RISCVVector::BI__builtin_rvv_sf_mm_e4m3_e4m3_w4:
case RISCVVector::BI__builtin_rvv_sf_mm_e4m3_e5m2_w4:
case RISCVVector::BI__builtin_rvv_sf_mm_u_u_w4:
case RISCVVector::BI__builtin_rvv_sf_mm_u_s_w4:
case RISCVVector::BI__builtin_rvv_sf_mm_s_u_w4:
case RISCVVector::BI__builtin_rvv_sf_mm_s_s_w4: {
QualType Arg1Type = TheCall->getArg(1)->getType();
ASTContext::BuiltinVectorTypeInfo Info =
SemaRef.Context.getBuiltinVectorTypeInfo(
Arg1Type->castAs<BuiltinType>());
unsigned EltSize = SemaRef.Context.getTypeSize(Info.ElementType);
llvm::APSInt Result;

// We can't check the value of a dependent argument.
Expr *Arg = TheCall->getArg(0);
if (Arg->isTypeDependent() || Arg->isValueDependent())
return false;

// Check constant-ness first.
if (SemaRef.BuiltinConstantArg(TheCall, 0, Result))
return true;

// For TEW = 32, mtd can only be 0, 4, 8, 12.
// For TEW = 64, mtd can only be 0, 2, 4, 6, 8, 10, 12, 14.
// Only `sf_mm_f_f_w1` and `sf_mm_f_f_w2` might have TEW = 64.
if ((BuiltinID == RISCVVector::BI__builtin_rvv_sf_mm_f_f_w1 &&
EltSize == 64) ||
(BuiltinID == RISCVVector::BI__builtin_rvv_sf_mm_f_f_w2 &&
EltSize == 32))
return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 15) ||
SemaRef.BuiltinConstantArgMultiple(TheCall, 0, 2);
return SemaRef.BuiltinConstantArgRange(TheCall, 0, 0, 15) ||
SemaRef.BuiltinConstantArgMultiple(TheCall, 0, 4);
}
case RISCVVector::BI__builtin_rvv_vget_v: {
ASTContext::BuiltinVectorTypeInfo ResVecInfo =
Context.getBuiltinVectorTypeInfo(cast<BuiltinType>(
Expand Down
11 changes: 9 additions & 2 deletions clang/lib/Support/RISCVVIntrinsicUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -978,11 +978,12 @@ RVVIntrinsic::RVVIntrinsic(
bool HasMaskedOffOperand, bool HasVL, PolicyScheme Scheme,
bool SupportOverloading, bool HasBuiltinAlias, StringRef ManualCodegen,
const RVVTypes &OutInTypes, const std::vector<int64_t> &NewIntrinsicTypes,
unsigned NF, Policy NewPolicyAttrs, bool HasFRMRoundModeOp)
unsigned NF, Policy NewPolicyAttrs, bool HasFRMRoundModeOp, unsigned TWiden)
: IRName(IRName), IsMasked(IsMasked),
HasMaskedOffOperand(HasMaskedOffOperand), HasVL(HasVL), Scheme(Scheme),
SupportOverloading(SupportOverloading), HasBuiltinAlias(HasBuiltinAlias),
ManualCodegen(ManualCodegen.str()), NF(NF), PolicyAttrs(NewPolicyAttrs) {
ManualCodegen(ManualCodegen.str()), NF(NF), PolicyAttrs(NewPolicyAttrs),
TWiden(TWiden) {

// Init BuiltinName, Name and OverloadedName
BuiltinName = NewName.str();
Expand Down Expand Up @@ -1233,6 +1234,12 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, enum RVVRequire Require) {
STRINGIFY(RVV_REQ_Zvfbfwma)
STRINGIFY(RVV_REQ_Zvfbfmin)
STRINGIFY(RVV_REQ_Zvfh)
STRINGIFY(RVV_REQ_Xsfmmbase)
STRINGIFY(RVV_REQ_Xsfmm32a8f)
STRINGIFY(RVV_REQ_Xsfmm32a16f)
STRINGIFY(RVV_REQ_Xsfmm32a32f)
STRINGIFY(RVV_REQ_Xsfmm64a64f)
STRINGIFY(RVV_REQ_Xsfmm32a8i)
STRINGIFY(RVV_REQ_Experimental)
default:
llvm_unreachable("Unsupported RVVRequire!");
Expand Down
Loading
Loading