diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp index 6d4d9469cec5b4..c935dad1687f4d 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.cpp +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.cpp @@ -32,20 +32,6 @@ using namespace llvm; static cl::opt EnableSubRegLiveness("riscv-enable-subreg-liveness", cl::init(false), cl::Hidden); -static cl::opt RVVVectorBitsMax( - "riscv-v-vector-bits-max", - cl::desc("Assume V extension vector registers are at most this big, " - "with zero meaning no maximum size is assumed."), - cl::init(0), cl::Hidden); - -static cl::opt RVVVectorBitsMin( - "riscv-v-vector-bits-min", - cl::desc("Assume V extension vector registers are at least this big, " - "with zero meaning no minimum size is assumed. A value of -1 " - "means use Zvl*b extension. This is primarily used to enable " - "autovectorization with fixed width vectors."), - cl::init(-1), cl::Hidden); - static cl::opt RVVVectorLMULMax( "riscv-v-fixed-length-vector-lmul-max", cl::desc("The maximum LMUL value to use for fixed length vectors. " @@ -89,8 +75,11 @@ RISCVSubtarget::initializeSubtargetDependencies(const Triple &TT, StringRef CPU, RISCVSubtarget::RISCVSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU, StringRef FS, - StringRef ABIName, const TargetMachine &TM) + StringRef ABIName, unsigned RVVVectorBitsMin, + unsigned RVVVectorBitsMax, + const TargetMachine &TM) : RISCVGenSubtargetInfo(TT, CPU, TuneCPU, FS), + RVVVectorBitsMin(RVVVectorBitsMin), RVVVectorBitsMax(RVVVectorBitsMax), FrameLowering( initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)), InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) { @@ -137,55 +126,30 @@ unsigned RISCVSubtarget::getMaxBuildIntsCost() const { unsigned RISCVSubtarget::getMaxRVVVectorSizeInBits() const { assert(hasVInstructions() && "Tried to get vector length without Zve or V extension support!"); - if (RVVVectorBitsMax == 0) - return 0; // ZvlLen specifies the minimum required vlen. The upper bound provided by // riscv-v-vector-bits-max should be no less than it. - if (RVVVectorBitsMax < (int)ZvlLen) + if (RVVVectorBitsMax != 0 && RVVVectorBitsMax < ZvlLen) report_fatal_error("riscv-v-vector-bits-max specified is lower " "than the Zvl*b limitation"); - // FIXME: Change to >= 32 when VLEN = 32 is supported - assert( - RVVVectorBitsMax >= 64 && RVVVectorBitsMax <= 65536 && - isPowerOf2_32(RVVVectorBitsMax) && - "V or Zve* extension requires vector length to be in the range of 64 to " - "65536 and a power of 2!"); - assert(RVVVectorBitsMax >= RVVVectorBitsMin && - "Minimum V extension vector length should not be larger than its " - "maximum!"); - unsigned Max = std::max(RVVVectorBitsMin, RVVVectorBitsMax); - return PowerOf2Floor((Max < 64 || Max > 65536) ? 0 : Max); + return RVVVectorBitsMax; } unsigned RISCVSubtarget::getMinRVVVectorSizeInBits() const { assert(hasVInstructions() && "Tried to get vector length without Zve or V extension support!"); - if (RVVVectorBitsMin == -1) + if (RVVVectorBitsMin == -1U) return ZvlLen; // ZvlLen specifies the minimum required vlen. The lower bound provided by // riscv-v-vector-bits-min should be no less than it. - if (RVVVectorBitsMin != 0 && RVVVectorBitsMin < (int)ZvlLen) + if (RVVVectorBitsMin != 0 && RVVVectorBitsMin < ZvlLen) report_fatal_error("riscv-v-vector-bits-min specified is lower " "than the Zvl*b limitation"); - // FIXME: Change to >= 32 when VLEN = 32 is supported - assert( - (RVVVectorBitsMin == 0 || - (RVVVectorBitsMin >= 64 && RVVVectorBitsMin <= 65536 && - isPowerOf2_32(RVVVectorBitsMin))) && - "V or Zve* extension requires vector length to be in the range of 64 to " - "65536 and a power of 2!"); - assert((RVVVectorBitsMax >= RVVVectorBitsMin || RVVVectorBitsMax == 0) && - "Minimum V extension vector length should not be larger than its " - "maximum!"); - unsigned Min = RVVVectorBitsMin; - if (RVVVectorBitsMax != 0) - Min = std::min(RVVVectorBitsMin, RVVVectorBitsMax); - return PowerOf2Floor((Min < 64 || Min > 65536) ? 0 : Min); + return RVVVectorBitsMin; } unsigned RISCVSubtarget::getMaxLMULForFixedLengthVectors() const { diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h index d19aa94fc945eb..8eaf04ba39c4ce 100644 --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -51,6 +51,8 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo { unsigned XLen = 32; unsigned ZvlLen = 0; MVT XLenVT = MVT::i32; + unsigned RVVVectorBitsMin; + unsigned RVVVectorBitsMax; uint8_t MaxInterleaveFactor = 2; RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown; std::bitset UserReservedRegister; @@ -71,7 +73,8 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo { public: // Initializes the data members to match that of the specified triple. RISCVSubtarget(const Triple &TT, StringRef CPU, StringRef TuneCPU, - StringRef FS, StringRef ABIName, const TargetMachine &TM); + StringRef FS, StringRef ABIName, unsigned RVVVectorBitsMin, + unsigned RVVVectorLMULMax, const TargetMachine &TM); // Parses features string setting specified subtarget options. The // definition of this function is auto-generated by tblgen. diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp index dff8ccccc3a608..fa13c6a484993e 100644 --- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp +++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp @@ -53,6 +53,20 @@ static cl::opt cl::desc("Enable the machine combiner pass"), cl::init(true), cl::Hidden); +static cl::opt RVVVectorBitsMaxOpt( + "riscv-v-vector-bits-max", + cl::desc("Assume V extension vector registers are at most this big, " + "with zero meaning no maximum size is assumed."), + cl::init(0), cl::Hidden); + +static cl::opt RVVVectorBitsMinOpt( + "riscv-v-vector-bits-min", + cl::desc("Assume V extension vector registers are at least this big, " + "with zero meaning no minimum size is assumed. A value of -1 " + "means use Zvl*b extension. This is primarily used to enable " + "autovectorization with fixed width vectors."), + cl::init(-1), cl::Hidden); + extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() { RegisterTargetMachine X(getTheRISCV32Target()); RegisterTargetMachine Y(getTheRISCV64Target()); @@ -109,7 +123,45 @@ RISCVTargetMachine::getSubtargetImpl(const Function &F) const { TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU; std::string FS = FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; - std::string Key = CPU + TuneCPU + FS; + + unsigned RVVBitsMin = RVVVectorBitsMinOpt; + unsigned RVVBitsMax = RVVVectorBitsMaxOpt; + + if (RVVBitsMin != -1U) { + // FIXME: Change to >= 32 when VLEN = 32 is supported. + assert((RVVBitsMin == 0 || (RVVBitsMin >= 64 && RVVBitsMin <= 65536 && + isPowerOf2_32(RVVBitsMin))) && + "V or Zve* extension requires vector length to be in the range of " + "64 to 65536 and a power 2!"); + assert((RVVBitsMax >= RVVBitsMin || RVVBitsMax == 0) && + "Minimum V extension vector length should not be larger than its " + "maximum!"); + } + assert((RVVBitsMax == 0 || (RVVBitsMax >= 64 && RVVBitsMax <= 65536 && + isPowerOf2_32(RVVBitsMax))) && + "V or Zve* extension requires vector length to be in the range of " + "64 to 65536 and a power 2!"); + + if (RVVBitsMin != -1U) { + if (RVVBitsMax != 0) { + RVVBitsMin = std::min(RVVBitsMin, RVVBitsMax); + RVVBitsMax = std::max(RVVBitsMin, RVVBitsMax); + } + + RVVBitsMin = + PowerOf2Floor((RVVBitsMin < 64 || RVVBitsMin > 65536) ? 0 : RVVBitsMin); + } + RVVBitsMax = + PowerOf2Floor((RVVBitsMax < 64 || RVVBitsMax > 65536) ? 0 : RVVBitsMax); + + SmallString<512> Key; + Key += "RVVMin"; + Key += std::to_string(RVVBitsMin); + Key += "RVVMax"; + Key += std::to_string(RVVBitsMax); + Key += CPU; + Key += TuneCPU; + Key += FS; auto &I = SubtargetMap[Key]; if (!I) { // This needs to be done before we create a new subtarget since any @@ -126,7 +178,8 @@ RISCVTargetMachine::getSubtargetImpl(const Function &F) const { } ABIName = ModuleTargetABI->getString(); } - I = std::make_unique(TargetTriple, CPU, TuneCPU, FS, ABIName, *this); + I = std::make_unique( + TargetTriple, CPU, TuneCPU, FS, ABIName, RVVBitsMin, RVVBitsMax, *this); } return I.get(); }