From e6ceec9c1d190cdd465548161df6c8ebbb327739 Mon Sep 17 00:00:00 2001 From: eopXD Date: Thu, 20 Jan 2022 10:16:00 -0800 Subject: [PATCH] [Clang][RISCV] Restrict rvv builtins with zve macros The `zve` extension specifies the maximum ELEN for both integer and floating point mode - defined by macro `__riscv_v_elen` and `__riscv_v_elen_fp`. This commit restricts the functions in riscv_vector.h by the zve defined macro-s. Change enum `RISCVExtension` to `RISCVPredefinedMacro` since now it contains not only extensions. Also added type alignment to it. Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D112986 --- clang/utils/TableGen/RISCVVEmitter.cpp | 72 +++++++++++++++----------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp index 84da6a5901a4..ea2d0b8d2f2f 100644 --- a/clang/utils/TableGen/RISCVVEmitter.cpp +++ b/clang/utils/TableGen/RISCVVEmitter.cpp @@ -100,6 +100,9 @@ public: bool isValid() const { return Valid; } bool isScalar() const { return Scale.hasValue() && Scale.getValue() == 0; } bool isVector() const { return Scale.hasValue() && Scale.getValue() != 0; } + bool isVector(unsigned Width) const { + return isVector() && ElementBitwidth == Width; + } bool isFloat() const { return ScalarType == ScalarTypeKind::Float; } bool isSignedInteger() const { return ScalarType == ScalarTypeKind::SignedInteger; @@ -134,13 +137,15 @@ private: using RVVTypePtr = RVVType *; using RVVTypes = std::vector; +using RISCVPredefinedMacroT = uint8_t; -enum RISCVExtension : uint8_t { +enum RISCVPredefinedMacro : RISCVPredefinedMacroT { Basic = 0, - F = 1 << 1, - D = 1 << 2, - Zfh = 1 << 3, - RV64 = 1 << 4, + Zfh = 1 << 1, + RV64 = 1 << 2, + VectorMaxELen64 = 1 << 3, + VectorMaxELenFp32 = 1 << 4, + VectorMaxELenFp64 = 1 << 5, }; // TODO refactor RVVIntrinsic class design after support all intrinsic @@ -164,7 +169,7 @@ private: // The types we use to obtain the specific LLVM intrinsic. They are index of // InputTypes. -1 means the return type. std::vector IntrinsicTypes; - uint8_t RISCVExtensions = 0; + RISCVPredefinedMacroT RISCVPredefinedMacros = 0; unsigned NF = 1; public: @@ -188,7 +193,9 @@ public: bool isMask() const { return IsMask; } StringRef getIRName() const { return IRName; } StringRef getManualCodegen() const { return ManualCodegen; } - uint8_t getRISCVExtensions() const { return RISCVExtensions; } + RISCVPredefinedMacroT getRISCVPredefinedMacros() const { + return RISCVPredefinedMacros; + } unsigned getNF() const { return NF; } const std::vector &getIntrinsicTypes() const { return IntrinsicTypes; @@ -251,7 +258,8 @@ private: // Emit the architecture preprocessor definitions. Return true when emits // non-empty string. - bool emitExtDefStr(uint8_t Extensions, raw_ostream &o); + bool emitMacroRestrictionStr(RISCVPredefinedMacroT PredefinedMacros, + raw_ostream &o); // Slice Prototypes string into sub prototype string and process each sub // prototype string individually in the Handler. void parsePrototypes(StringRef Prototypes, @@ -789,15 +797,17 @@ RVVIntrinsic::RVVIntrinsic(StringRef NewName, StringRef Suffix, // Init RISC-V extensions for (const auto &T : OutInTypes) { if (T->isFloatVector(16) || T->isFloat(16)) - RISCVExtensions |= RISCVExtension::Zfh; - else if (T->isFloatVector(32) || T->isFloat(32)) - RISCVExtensions |= RISCVExtension::F; - else if (T->isFloatVector(64) || T->isFloat(64)) - RISCVExtensions |= RISCVExtension::D; + RISCVPredefinedMacros |= RISCVPredefinedMacro::Zfh; + if (T->isFloatVector(32)) + RISCVPredefinedMacros |= RISCVPredefinedMacro::VectorMaxELenFp32; + if (T->isFloatVector(64)) + RISCVPredefinedMacros |= RISCVPredefinedMacro::VectorMaxELenFp64; + if (T->isVector(64)) + RISCVPredefinedMacros |= RISCVPredefinedMacro::VectorMaxELen64; } for (auto Extension : RequiredExtensions) { if (Extension == "RV64") - RISCVExtensions |= RISCVExtension::RV64; + RISCVPredefinedMacros |= RISCVPredefinedMacro::RV64; } // Init OutputType and InputTypes @@ -981,7 +991,7 @@ void RVVEmitter::createHeader(raw_ostream &OS) { // The same extension include in the same arch guard marco. llvm::stable_sort(Defs, [](const std::unique_ptr &A, const std::unique_ptr &B) { - return A->getRISCVExtensions() < B->getRISCVExtensions(); + return A->getRISCVPredefinedMacros() < B->getRISCVPredefinedMacros(); }); OS << "#define __rvv_ai static __inline__\n"; @@ -1280,15 +1290,16 @@ Optional RVVEmitter::computeType(BasicType BT, int Log2LMUL, void RVVEmitter::emitArchMacroAndBody( std::vector> &Defs, raw_ostream &OS, std::function PrintBody) { - uint8_t PrevExt = (*Defs.begin())->getRISCVExtensions(); - bool NeedEndif = emitExtDefStr(PrevExt, OS); + RISCVPredefinedMacroT PrevMacros = + (*Defs.begin())->getRISCVPredefinedMacros(); + bool NeedEndif = emitMacroRestrictionStr(PrevMacros, OS); for (auto &Def : Defs) { - uint8_t CurExt = Def->getRISCVExtensions(); - if (CurExt != PrevExt) { + RISCVPredefinedMacroT CurMacros = Def->getRISCVPredefinedMacros(); + if (CurMacros != PrevMacros) { if (NeedEndif) OS << "#endif\n\n"; - NeedEndif = emitExtDefStr(CurExt, OS); - PrevExt = CurExt; + NeedEndif = emitMacroRestrictionStr(CurMacros, OS); + PrevMacros = CurMacros; } if (Def->hasAutoDef()) PrintBody(OS, *Def); @@ -1297,19 +1308,22 @@ void RVVEmitter::emitArchMacroAndBody( OS << "#endif\n\n"; } -bool RVVEmitter::emitExtDefStr(uint8_t Extents, raw_ostream &OS) { - if (Extents == RISCVExtension::Basic) +bool RVVEmitter::emitMacroRestrictionStr(RISCVPredefinedMacroT PredefinedMacros, + raw_ostream &OS) { + if (PredefinedMacros == RISCVPredefinedMacro::Basic) return false; OS << "#if "; ListSeparator LS(" && "); - if (Extents & RISCVExtension::F) - OS << LS << "defined(__riscv_f)"; - if (Extents & RISCVExtension::D) - OS << LS << "defined(__riscv_d)"; - if (Extents & RISCVExtension::Zfh) + if (PredefinedMacros & RISCVPredefinedMacro::Zfh) OS << LS << "defined(__riscv_zfh)"; - if (Extents & RISCVExtension::RV64) + if (PredefinedMacros & RISCVPredefinedMacro::RV64) OS << LS << "(__riscv_xlen == 64)"; + if (PredefinedMacros & RISCVPredefinedMacro::VectorMaxELen64) + OS << LS << "(__riscv_v_elen >= 64)"; + if (PredefinedMacros & RISCVPredefinedMacro::VectorMaxELenFp32) + OS << LS << "(__riscv_v_elen_fp >= 32)"; + if (PredefinedMacros & RISCVPredefinedMacro::VectorMaxELenFp64) + OS << LS << "(__riscv_v_elen_fp >= 64)"; OS << "\n"; return true; }