diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -188,7 +188,7 @@ if (ISAInfo->hasExtension("c")) Builder.defineMacro("__riscv_compressed"); - if (ISAInfo->hasExtension("zve32x")) + if (ISAInfo->hasExtension("zve32x") || ISAInfo->hasExtension("v")) Builder.defineMacro("__riscv_vector"); } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3975,23 +3975,37 @@ // Check if each required feature is included for (StringRef F : ReqFeatures) { - if (TI.hasFeature(F)) - continue; - - // If the feature is 64bit, alter the string so it will print better in - // the diagnostic. - if (F == "64bit") - F = "RV64"; - - // Convert features like "zbr" and "experimental-zbr" to "Zbr". - F.consume_front("experimental-"); - std::string FeatureStr = F.str(); - FeatureStr[0] = std::toupper(FeatureStr[0]); + SmallVector ReqOpFeatures; + F.split(ReqOpFeatures, '|'); + bool HasFeature = false; + for (StringRef OF : ReqOpFeatures) { + if (TI.hasFeature(OF)) { + HasFeature = true; + continue; + } + } - // Error message - FeatureMissing = true; - Diag(TheCall->getBeginLoc(), diag::err_riscv_builtin_requires_extension) - << TheCall->getSourceRange() << StringRef(FeatureStr); + if (!HasFeature) { + std::string FeatureStrs = ""; + for (StringRef OF : ReqOpFeatures) { + // If the feature is 64bit, alter the string so it will print better in + // the diagnostic. + if (OF == "64bit") + OF = "RV64"; + + // 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 == "" ? "" : " or "; + FeatureStrs += FeatureStr; + } + // Error message + FeatureMissing = true; + Diag(TheCall->getBeginLoc(), diag::err_riscv_builtin_requires_extension) + << TheCall->getSourceRange() << StringRef(FeatureStrs); + } } if (FeatureMissing) diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp --- a/clang/utils/TableGen/RISCVVEmitter.cpp +++ b/clang/utils/TableGen/RISCVVEmitter.cpp @@ -1024,7 +1024,7 @@ OS << "#if defined(TARGET_BUILTIN) && !defined(RISCVV_BUILTIN)\n"; OS << "#define RISCVV_BUILTIN(ID, TYPE, ATTRS) TARGET_BUILTIN(ID, TYPE, " - "ATTRS, \"experimental-zve32x\")\n"; + "ATTRS, \"experimental-zve32x|experimental-v\")\n"; OS << "#endif\n"; for (auto &Def : Defs) { auto P = diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -688,9 +688,11 @@ bool HasE = Exts.count("e") == 1; bool HasD = Exts.count("d") == 1; bool HasF = Exts.count("f") == 1; - bool HasVector = Exts.count("zve32x") == 1; + bool HasZve32x = Exts.count("zve32x") == 1; bool HasZve32f = Exts.count("zve32f") == 1; bool HasZve64d = Exts.count("zve64d") == 1; + bool HasV = Exts.count("v") == 1; + bool HasVector = HasZve32x || HasV; bool HasZvl = MinVLen != 0; if (HasE && !IsRv32) @@ -730,7 +732,7 @@ return Error::success(); } -static const char *ImpliedExtsV[] = {"zvl128b", "zve64d", "f", "d"}; +static const char *ImpliedExtsV[] = {"zvl128b", "f", "d"}; static const char *ImpliedExtsZfh[] = {"zfhmin"}; static const char *ImpliedExtsZve64d[] = {"zve64f"}; static const char *ImpliedExtsZve64f[] = {"zve64x", "zve32f"}; @@ -853,6 +855,11 @@ ExtName.getAsInteger(10, ZveELen); MaxELen = std::max(MaxELen, ZveELen); } + if (ExtName == "v") { + MaxELenFp = 64; + MaxELen = 64; + return; + } } } diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -193,21 +193,21 @@ def FeatureStdExtV : SubtargetFeature<"experimental-v", "HasStdExtV", "true", "'V' (Vector Extension for Application Processors)", - [FeatureStdExtZvl128b, FeatureStdExtZve64d, FeatureStdExtF, FeatureStdExtD]>; + [FeatureStdExtZvl128b, FeatureStdExtF, FeatureStdExtD]>; def HasVInstructions : Predicate<"Subtarget->hasVInstructions()">, AssemblerPredicate< - (any_of FeatureStdExtZve32x), + (any_of FeatureStdExtZve32x, FeatureStdExtV), "'V' (Vector Extension for Application Processors), 'Zve32x' or " "'Zve64x' (Vector Extensions for Embedded Processors)">; def HasVInstructionsI64 : Predicate<"Subtarget->hasVInstructionsI64()">, AssemblerPredicate< - (any_of FeatureStdExtZve64x), + (any_of FeatureStdExtZve64x, FeatureStdExtV), "'V' (Vector Extension for Application Processors) or 'Zve64x' " "(Vector Extensions for Embedded Processors)">; def HasVInstructionsAnyF : Predicate<"Subtarget->hasVInstructionsAnyF()">, AssemblerPredicate< - (any_of FeatureStdExtZve32f), + (any_of FeatureStdExtZve32f, FeatureStdExtV), "'V' (Vector Extension for Application Processors), 'Zve32f', " "'Zve64f' or 'Zve64d' (Vector Extensions for Embedded Processors)">; diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -179,13 +179,19 @@ } // Vector codegen related methods. - bool hasVInstructions() const { return HasStdExtZve32x; } - bool hasVInstructionsI64() const { return HasStdExtZve64x; } - bool hasVInstructionsF16() const { return HasStdExtZve32f && HasStdExtZfh; } + bool hasVInstructions() const { return HasStdExtV || HasStdExtZve32x; } + bool hasVInstructionsI64() const { return HasStdExtV || HasStdExtZve64x; } + bool hasVInstructionsF16() const { + return HasStdExtV || (HasStdExtZve32f && HasStdExtZfh); + } // FIXME: Consider Zfinx in the future - bool hasVInstructionsF32() const { return HasStdExtZve32f && HasStdExtF; } + bool hasVInstructionsF32() const { + return HasStdExtV || (HasStdExtZve32f && HasStdExtF); + } // FIXME: Consider Zdinx in the future - bool hasVInstructionsF64() const { return HasStdExtZve64d && HasStdExtD; } + bool hasVInstructionsF64() const { + return HasStdExtV || (HasStdExtZve64d && HasStdExtD); + } // F16 and F64 both require F32. bool hasVInstructionsAnyF() const { return hasVInstructionsF32(); } unsigned getMaxInterleaveFactor() const {