frasercrmck updated this revision to Diff 367232.
frasercrmck added a comment.
Herald added subscribers: llvm-commits, hiraditya.
Herald added a project: LLVM.

update usage in vein of AArch64:

- use vscale_range attribute to determine RVV vector bits min/max values
- if no attribute is present, use existing backend flags
- sanitize and pass RVV vector bits from RISCVTargetMachine through to 
RISCVSubtarget
- RISCVSubtarget just stores and reports


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/lib/Target/RISCV/RISCVSubtarget.cpp
  llvm/lib/Target/RISCV/RISCVSubtarget.h
  llvm/lib/Target/RISCV/RISCVTargetMachine.cpp

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,50 @@
   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 % 128 == 0 &&
+         "RVV requires vector length in multiples of 128!");
+  assert(RVVBitsMax % 128 == 0 &&
+         "RVV requires vector length in multiples of 128!");
+  assert(RVVBitsMax <= 65536 &&
+         "RVV vector size must be no larger than 65536!");
+  assert((RVVBitsMax >= RVVBitsMin || RVVBitsMax == 0) &&
+         "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 < 128 || RVVBitsMin > 65536) ? 0 : RVVBitsMin);
+
+  RVVBitsMax = std::max(RVVBitsMin, RVVBitsMax);
+  RVVBitsMax =
+      PowerOf2Floor((RVVBitsMax < 128 || RVVBitsMax > 65536) ? 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 +150,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;
   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. "
@@ -75,10 +63,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));
@@ -105,38 +97,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: 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
@@ -111,7 +111,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,20 @@
   return true;
 }
 
+Optional<std::pair<unsigned, unsigned>>
+RISCVTargetInfo::getVScaleRange(const LangOptions &LangOpts) const {
+  if (!HasV)
+    return None;
+  // VLEN is defined in v0.10 to be at least 128 bits and at most 65536 bits,
+  // and vscale is VLEN/64.
+  // FIXME: v1.0 removes 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 = 128;
+  unsigned VLENMax = 65536;
+  return std::make_pair(VLENMin / 64, VLENMax / 64);
+}
+
 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