aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorBrandon Wu <brandon.wu@sifive.com>2024-03-27 23:22:01 +0800
committerGitHub <noreply@github.com>2024-03-27 23:22:01 +0800
commit13b653ab112736b92cd7f8ef249ced2b148ee7f4 (patch)
tree7c022feeb4ebddf0692d4ebc2f0941c277b80d16 /clang/lib/Sema/SemaChecking.cpp
parent58de1e2c5eee548a9b365e3b1554d87317072ad9 (diff)
downloadllvm-13b653ab112736b92cd7f8ef249ced2b148ee7f4.zip
llvm-13b653ab112736b92cd7f8ef249ced2b148ee7f4.tar.gz
llvm-13b653ab112736b92cd7f8ef249ced2b148ee7f4.tar.bz2
[clang][RISCV] Enable RVV with function attribute __attribute__((target("arch=+v"))) (#83674)
It is currently not possible to use "RVV type" and "RVV intrinsics" if the "zve32x" is not enabled globally. However in some cases we may want to use them only in some functions, for instance: ``` #include <riscv_vector.h> __attribute__((target("+zve32x"))) vint32m1_t rvv_add(vint32m1_t v1, vint32m1_t v2, size_t vl) { return __riscv_vadd(v1, v2, vl); } int other_add(int i1, int i2) { return i1 + i2; } ``` , it is supposed to be compilable even the vector is not specified, e.g. `clang -target riscv64 -march=rv64gc -S test.c`.
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp70
1 files changed, 9 insertions, 61 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 0844958..447e736 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -5760,57 +5760,6 @@ static bool CheckInvalidVLENandLMUL(const TargetInfo &TI, CallExpr *TheCall,
bool Sema::CheckRISCVBuiltinFunctionCall(const TargetInfo &TI,
unsigned BuiltinID,
CallExpr *TheCall) {
- // CodeGenFunction can also detect this, but this gives a better error
- // message.
- bool FeatureMissing = false;
- SmallVector<StringRef> ReqFeatures;
- StringRef Features = Context.BuiltinInfo.getRequiredFeatures(BuiltinID);
- Features.split(ReqFeatures, ',', -1, false);
-
- // Check if each required feature is included
- for (StringRef F : ReqFeatures) {
- SmallVector<StringRef> ReqOpFeatures;
- F.split(ReqOpFeatures, '|');
-
- if (llvm::none_of(ReqOpFeatures,
- [&TI](StringRef OF) { return TI.hasFeature(OF); })) {
- std::string FeatureStrs;
- bool IsExtension = true;
- for (StringRef OF : ReqOpFeatures) {
- // If the feature is 64bit, alter the string so it will print better in
- // the diagnostic.
- if (OF == "64bit") {
- assert(ReqOpFeatures.size() == 1 && "Expected '64bit' to be alone");
- OF = "RV64";
- IsExtension = false;
- }
- if (OF == "32bit") {
- assert(ReqOpFeatures.size() == 1 && "Expected '32bit' to be alone");
- OF = "RV32";
- IsExtension = false;
- }
-
- // Convert features like "zbr" and "experimental-zbr" to "Zbr".
- OF.consume_front("experimental-");
- std::string FeatureStr = OF.str();
- FeatureStr[0] = std::toupper(FeatureStr[0]);
- // Combine strings.
- FeatureStrs += FeatureStrs.empty() ? "" : ", ";
- FeatureStrs += "'";
- FeatureStrs += FeatureStr;
- FeatureStrs += "'";
- }
- // Error message
- FeatureMissing = true;
- Diag(TheCall->getBeginLoc(), diag::err_riscv_builtin_requires_extension)
- << IsExtension
- << TheCall->getSourceRange() << StringRef(FeatureStrs);
- }
- }
-
- if (FeatureMissing)
- return true;
-
// vmulh.vv, vmulh.vx, vmulhu.vv, vmulhu.vx, vmulhsu.vv, vmulhsu.vx,
// vsmul.vv, vsmul.vx are not included for EEW=64 in Zve64*.
switch (BuiltinID) {
@@ -6714,36 +6663,35 @@ bool Sema::CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI,
return false;
}
-void Sema::checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D) {
- const TargetInfo &TI = Context.getTargetInfo();
-
+void Sema::checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D,
+ const llvm::StringMap<bool> &FeatureMap) {
ASTContext::BuiltinVectorTypeInfo Info =
Context.getBuiltinVectorTypeInfo(Ty->castAs<BuiltinType>());
unsigned EltSize = Context.getTypeSize(Info.ElementType);
unsigned MinElts = Info.EC.getKnownMinValue();
if (Info.ElementType->isSpecificBuiltinType(BuiltinType::Double) &&
- !TI.hasFeature("zve64d"))
+ !FeatureMap.lookup("zve64d"))
Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve64d";
// (ELEN, LMUL) pairs of (8, mf8), (16, mf4), (32, mf2), (64, m1) requires at
// least zve64x
else if (((EltSize == 64 && Info.ElementType->isIntegerType()) ||
MinElts == 1) &&
- !TI.hasFeature("zve64x"))
+ !FeatureMap.lookup("zve64x"))
Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve64x";
- else if (Info.ElementType->isFloat16Type() && !TI.hasFeature("zvfh") &&
- !TI.hasFeature("zvfhmin"))
+ else if (Info.ElementType->isFloat16Type() && !FeatureMap.lookup("zvfh") &&
+ !FeatureMap.lookup("zvfhmin"))
Diag(Loc, diag::err_riscv_type_requires_extension, D)
<< Ty << "zvfh or zvfhmin";
else if (Info.ElementType->isBFloat16Type() &&
- !TI.hasFeature("experimental-zvfbfmin"))
+ !FeatureMap.lookup("experimental-zvfbfmin"))
Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zvfbfmin";
else if (Info.ElementType->isSpecificBuiltinType(BuiltinType::Float) &&
- !TI.hasFeature("zve32f"))
+ !FeatureMap.lookup("zve32f"))
Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve32f";
// Given that caller already checked isRVVType() before calling this function,
// if we don't have at least zve32x supported, then we need to emit error.
- else if (!TI.hasFeature("zve32x"))
+ else if (!FeatureMap.lookup("zve32x"))
Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve32x";
}