frasercrmck updated this revision to Diff 369416.
frasercrmck marked 2 inline comments as done.
frasercrmck added a comment.
Herald added a subscriber: dexonsmith.

- rebase
- move V VLEN bits-per-block (64), min (128), max (65536) defines into 
TargetParser.h
- clean up assertions


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D107290/new/

https://reviews.llvm.org/D107290

Files:
  clang/lib/Basic/Targets/RISCV.cpp
  clang/lib/Basic/Targets/RISCV.h
  clang/test/CodeGen/riscv-vscale-range.c
  llvm/include/llvm/Support/TargetParser.h
  llvm/lib/Target/RISCV/RISCVISelLowering.cpp
  llvm/lib/Target/RISCV/RISCVISelLowering.h
  llvm/lib/Target/RISCV/RISCVSubtarget.cpp
  llvm/lib/Target/RISCV/RISCVSubtarget.h
  llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
  llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h

Index: llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
===================================================================
--- llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
+++ llvm/lib/Target/RISCV/RISCVTargetTransformInfo.h
@@ -21,6 +21,7 @@
 #include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/CodeGen/BasicTTIImpl.h"
 #include "llvm/IR/Function.h"
+#include "llvm/Support/TargetParser.h"
 
 namespace llvm {
 
Index: llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -32,6 +32,18 @@
 #include "llvm/Target/TargetOptions.h"
 using namespace llvm;
 
+static cl::opt<unsigned> 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<unsigned> 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."),
+    cl::init(0), cl::Hidden);
+
 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
   RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target());
   RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target());
@@ -78,13 +90,58 @@
   Attribute TuneAttr = F.getFnAttribute("tune-cpu");
   Attribute FSAttr = F.getFnAttribute("target-features");
 
+  unsigned RVVBitsMin = 0;
+  unsigned RVVBitsMax = 0;
+  Attribute VScaleRangeAttr = F.getFnAttribute(Attribute::VScaleRange);
+  if (VScaleRangeAttr.isValid()) {
+    std::tie(RVVBitsMin, RVVBitsMax) = VScaleRangeAttr.getVScaleRangeArgs();
+    RVVBitsMin *= RISCV::RVVBitsPerBlock;
+    RVVBitsMax *= RISCV::RVVBitsPerBlock;
+  } else {
+    RVVBitsMin = RVVVectorBitsMinOpt;
+    RVVBitsMax = RVVVectorBitsMaxOpt;
+  }
+
+  assert((RVVBitsMin == 0 || isPowerOf2_32(RVVBitsMin)) &&
+         "RVV requires vector length to be a power of two!");
+  assert((RVVBitsMax == 0 || isPowerOf2_32(RVVBitsMax)) &&
+         "RVV requires vector length to be a power of two!");
+  assert((RVVBitsMin == 0 || RVVBitsMin >= RISCV::StdVVLENBitsMin) &&
+         "RVV vector size must be no smaller than the minimum allowed by the "
+         "specification!");
+  assert(RVVBitsMax <= RISCV::StdVVLENBitsMax &&
+         "RVV vector size must be no larger than the maximum allowed by the "
+         "specification!");
+  assert((RVVBitsMax == 0 || RVVBitsMax >= RVVBitsMin) &&
+         "Minimum RVV vector size should not be larger than its maximum!");
+
+  // Sanitize user input in case of no asserts.
+  if (RVVBitsMax != 0)
+    RVVBitsMin = std::min(RVVBitsMin, RVVBitsMax);
+  RVVBitsMin = PowerOf2Floor((RVVBitsMin < RISCV::StdVVLENBitsMin ||
+                              RVVBitsMin > RISCV::StdVVLENBitsMax)
+                                 ? 0
+                                 : RVVBitsMin);
+
+  RVVBitsMax = std::max(RVVBitsMin, RVVBitsMax);
+  RVVBitsMax = PowerOf2Floor((RVVBitsMax < RISCV::StdVVLENBitsMin ||
+                              RVVBitsMax > RISCV::StdVVLENBitsMax)
+                                 ? 0
+                                 : RVVBitsMax);
+
   std::string CPU =
       CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU;
   std::string TuneCPU =
       TuneAttr.isValid() ? TuneAttr.getValueAsString().str() : CPU;
   std::string FS =
       FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
+
   std::string Key = CPU + TuneCPU + FS;
+  Key += "RVVMin";
+  Key += std::to_string(RVVBitsMin);
+  Key += "RVVMax";
+  Key += std::to_string(RVVBitsMax);
+
   auto &I = SubtargetMap[Key];
   if (!I) {
     // This needs to be done before we create a new subtarget since any
@@ -101,7 +158,8 @@
       }
       ABIName = ModuleTargetABI->getString();
     }
-    I = std::make_unique<RISCVSubtarget>(TargetTriple, CPU, TuneCPU, FS, ABIName, *this);
+    I = std::make_unique<RISCVSubtarget>(
+        TargetTriple, CPU, TuneCPU, FS, ABIName, RVVBitsMin, RVVBitsMax, *this);
   }
   return I.get();
 }
Index: llvm/lib/Target/RISCV/RISCVSubtarget.h
===================================================================
--- llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -62,6 +62,8 @@
   bool EnableSaveRestore = false;
   unsigned XLen = 32;
   MVT XLenVT = MVT::i32;
+  unsigned RVVVectorBitsMin;
+  unsigned RVVVectorBitsMax;
   uint8_t MaxInterleaveFactor = 2;
   RISCVABI::ABI TargetABI = RISCVABI::ABI_Unknown;
   BitVector UserReservedRegister;
@@ -82,7 +84,8 @@
 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.
@@ -155,8 +158,16 @@
   // Return the known range for the bit length of RVV data registers. A value
   // of 0 means nothing is known about that particular limit beyond what's
   // implied by the architecture.
-  unsigned getMaxRVVVectorSizeInBits() const;
-  unsigned getMinRVVVectorSizeInBits() const;
+  unsigned getMaxRVVVectorSizeInBits() const {
+    assert(hasStdExtV() &&
+           "Tried to get vector length without V extension support!");
+    return RVVVectorBitsMax;
+  }
+  unsigned getMinRVVVectorSizeInBits() const {
+    assert(hasStdExtV() &&
+           "Tried to get vector length without V extension support!");
+    return RVVVectorBitsMin;
+  }
   unsigned getMaxLMULForFixedLengthVectors() const;
   unsigned getMaxELENForFixedLengthVectors() const;
   bool useRVVForFixedLengthVectors() const;
Index: llvm/lib/Target/RISCV/RISCVSubtarget.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVSubtarget.cpp
+++ llvm/lib/Target/RISCV/RISCVSubtarget.cpp
@@ -27,18 +27,6 @@
 #define GET_SUBTARGETINFO_CTOR
 #include "RISCVGenSubtargetInfo.inc"
 
-static cl::opt<unsigned> 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<unsigned> 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."),
-    cl::init(0), cl::Hidden);
-
 static cl::opt<unsigned> RVVVectorLMULMax(
     "riscv-v-fixed-length-vector-lmul-max",
     cl::desc("The maximum LMUL value to use for fixed length vectors. "
@@ -80,10 +68,14 @@
 
 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),
       UserReservedRegister(RISCV::NUM_TARGET_REGS),
-      FrameLowering(initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
+      FrameLowering(
+          initializeSubtargetDependencies(TT, CPU, TuneCPU, FS, ABIName)),
       InstrInfo(*this), RegInfo(getHwMode()), TLInfo(TM, *this) {
   CallLoweringInfo.reset(new RISCVCallLowering(*getTargetLowering()));
   Legalizer.reset(new RISCVLegalizerInfo(*this));
@@ -110,38 +102,6 @@
   return RegBankInfo.get();
 }
 
-unsigned RISCVSubtarget::getMaxRVVVectorSizeInBits() const {
-  assert(hasStdExtV() && "Tried to get vector length without V support!");
-  if (RVVVectorBitsMax == 0)
-    return 0;
-  assert(RVVVectorBitsMax >= 128 && RVVVectorBitsMax <= 65536 &&
-         isPowerOf2_32(RVVVectorBitsMax) &&
-         "V extension requires vector length to be in the range of 128 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 < 128 || Max > 65536) ? 0 : Max);
-}
-
-unsigned RISCVSubtarget::getMinRVVVectorSizeInBits() const {
-  assert(hasStdExtV() &&
-         "Tried to get vector length without V extension support!");
-  assert((RVVVectorBitsMin == 0 ||
-          (RVVVectorBitsMin >= 128 && RVVVectorBitsMax <= 65536 &&
-           isPowerOf2_32(RVVVectorBitsMin))) &&
-         "V extension requires vector length to be in the range of 128 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 < 128 || Min > 65536) ? 0 : Min);
-}
-
 unsigned RISCVSubtarget::getMaxLMULForFixedLengthVectors() const {
   assert(hasStdExtV() &&
          "Tried to get maximum LMUL without V extension support!");
Index: llvm/lib/Target/RISCV/RISCVISelLowering.h
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -613,11 +613,6 @@
   bool mergeStoresAfterLegalization(EVT VT) const override;
 };
 
-namespace RISCV {
-// We use 64 bits as the known part in the scalable vector types.
-static constexpr unsigned RVVBitsPerBlock = 64;
-} // namespace RISCV
-
 namespace RISCVVIntrinsicsTable {
 
 struct RISCVVIntrinsicInfo {
Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -34,6 +34,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/KnownBits.h"
 #include "llvm/Support/MathExtras.h"
+#include "llvm/Support/TargetParser.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
Index: llvm/include/llvm/Support/TargetParser.h
===================================================================
--- llvm/include/llvm/Support/TargetParser.h
+++ llvm/include/llvm/Support/TargetParser.h
@@ -175,6 +175,14 @@
 bool getCPUFeaturesExceptStdExt(CPUKind Kind, std::vector<StringRef> &Features);
 StringRef resolveTuneCPUAlias(StringRef TuneCPU, bool IsRV64);
 
+// We use 64 bits as the known part in the scalable vector types.
+static constexpr unsigned RVVBitsPerBlock = 64;
+// The standard "capital V" specification-defined lower- and upper-bounds on
+// VLEN, in bits. Note that other extensions like the Zvl extensions may change
+// these values.
+static constexpr unsigned StdVVLENBitsMin = 128;
+static constexpr unsigned StdVVLENBitsMax = 65535;
+
 } // namespace RISCV
 
 } // namespace llvm
Index: clang/test/CodeGen/riscv-vscale-range.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/riscv-vscale-range.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple riscv64 -target-feature +experimental-v -S -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: @func() #0
+// CHECK: attributes #0 = { {{.*}} vscale_range(2,1024) {{.*}} }
+void func() {}
Index: clang/lib/Basic/Targets/RISCV.h
===================================================================
--- clang/lib/Basic/Targets/RISCV.h
+++ clang/lib/Basic/Targets/RISCV.h
@@ -116,7 +116,11 @@
                             DiagnosticsEngine &Diags) override;
 
   bool hasExtIntType() const override { return true; }
+
+  Optional<std::pair<unsigned, unsigned>>
+  getVScaleRange(const LangOptions &LangOpts) const override;
 };
+
 class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
 public:
   RISCV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Index: clang/lib/Basic/Targets/RISCV.cpp
===================================================================
--- clang/lib/Basic/Targets/RISCV.cpp
+++ clang/lib/Basic/Targets/RISCV.cpp
@@ -335,6 +335,21 @@
   return true;
 }
 
+Optional<std::pair<unsigned, unsigned>>
+RISCVTargetInfo::getVScaleRange(const LangOptions &LangOpts) const {
+  if (!HasV)
+    return None;
+  // RVV's vscale is defined as VLEN/RVVBitsPerBlock.
+  // FIXME: Other extensions like zvl64b and zvl32b may lower the minimum
+  // value.
+  // FIXME: The backend can be told about the more specific minimum/maximum
+  // VLEN but the frontend can't access this information.
+  unsigned VLENMin = llvm::RISCV::StdVVLENBitsMin;
+  unsigned VLENMax = llvm::RISCV::StdVVLENBitsMax;
+  return std::make_pair(VLENMin / llvm::RISCV::RVVBitsPerBlock,
+                        VLENMax / llvm::RISCV::RVVBitsPerBlock);
+}
+
 bool RISCV32TargetInfo::isValidCPUName(StringRef Name) const {
   return llvm::RISCV::checkCPUKind(llvm::RISCV::parseCPUKind(Name),
                                    /*Is64Bit=*/false);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to