craig.topper created this revision.
craig.topper added reviewers: reames, kito-cheng, frasercrmck, rogfer01.
Herald added subscribers: luke, VincentWu, ctetreau, vkmr, evandro, 
luismarques, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, jocewei, 
PkmX, the_o, brucehoult, MartinMosbeck, edward-jones, zzheng, jrtc27, 
shiva0217, niosHD, sabuasal, simoncook, johnrusso, rbar, asb, kristof.beyls, 
tschuett, arichardson.
Herald added a project: All.
craig.topper requested review of this revision.
Herald added subscribers: cfe-commits, pcwang-thead, eopXD, MaskRay.
Herald added a project: clang.

This option will control the vscale min/max.

I have left out the '+' support that SVE supports for now. We already
have minimum controlled by the Zvl*b extension so this didn't seem that
useful.

In addition to 64, 128, 256, 512, ..., 65536, I have added an extra
value "zvl" that will use the value from Zvl*b as the min and max.
This avoids repeating the numeric value in two places or to get
min/max from -mcpu.

The primary effect of this option today is simplification of stack
address calculations for RVV vectors and avoiding the use of
vrgatherei16 in some cases if we know there are less than 256 elements.

Future patches may add something similar to the arm_sve_vector_bits
attribute to allow RVV vectors to be used in structs and global
variables.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D142144

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Driver/Options.td
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/Driver/riscv-rvv-vector-bits.c

Index: clang/test/Driver/riscv-rvv-vector-bits.c
===================================================================
--- /dev/null
+++ clang/test/Driver/riscv-rvv-vector-bits.c
@@ -0,0 +1,45 @@
+// -----------------------------------------------------------------------------
+// Tests for the -msve-vector-bits flag
+// -----------------------------------------------------------------------------
+
+// RUN: %clang -c %s -### -target riscv64-linux-gnu -march=rv64gc_zve64x \
+// RUN:  -mrvv-vector-bits=128 2>&1 | FileCheck --check-prefix=CHECK-128 %s
+// RUN: %clang -c %s -### -target riscv64-linux-gnu -march=rv64gc_zve64x \
+// RUN:  -mrvv-vector-bits=256 2>&1 | FileCheck --check-prefix=CHECK-256 %s
+// RUN: %clang -c %s -### -target riscv64-linux-gnu -march=rv64gc_zve64x \
+// RUN:  -mrvv-vector-bits=512 2>&1 | FileCheck --check-prefix=CHECK-512 %s
+// RUN: %clang -c %s -### -target riscv64-linux-gnu -march=rv64gc_zve64x \
+// RUN:  -mrvv-vector-bits=1024 2>&1 | FileCheck --check-prefix=CHECK-1024 %s
+// RUN: %clang -c %s -### -target riscv64-linux-gnu -march=rv64gc_zve64x \
+// RUN:  -mrvv-vector-bits=2048 2>&1 | FileCheck --check-prefix=CHECK-2048 %s
+// RUN: %clang -c %s -### -target riscv64-linux-gnu -march=rv64gc_zve64x \
+// RUN:  -mrvv-vector-bits=scalable 2>&1 | FileCheck --check-prefix=CHECK-SCALABLE %s
+
+// RUN: %clang -c %s -### -target riscv64-linux-gnu -march=rv64gcv_zvl256b \
+// RUN:  -mrvv-vector-bits=zvl 2>&1 | FileCheck --check-prefix=CHECK-256 %s
+// RUN: %clang -c %s -### -target riscv64-linux-gnu -march=rv64gcv_zvl512b \
+// RUN:  -mrvv-vector-bits=zvl 2>&1 | FileCheck --check-prefix=CHECK-512 %s
+
+// CHECK-128: "-mvscale-max=2" "-mvscale-min=2"
+// CHECK-256: "-mvscale-max=4" "-mvscale-min=4"
+// CHECK-512: "-mvscale-max=8" "-mvscale-min=8"
+// CHECK-1024: "-mvscale-max=16" "-mvscale-min=16"
+// CHECK-2048: "-mvscale-max=32" "-mvscale-min=32"
+
+// CHECK-SCALABLE-NOT: "-mvscale-min=
+// CHECK-SCALABLE-NOT: "-mvscale-max=
+
+// Error out if an unsupported value is passed to -mrvv-vector-bits.
+// -----------------------------------------------------------------------------
+// RUN: %clang -c %s -### -target riscv64-linux-gnu -march=rv64gc_zve64x \
+// RUN:  -mrvv-vector-bits=16 2>&1 | FileCheck --check-prefix=CHECK-BAD-VALUE-ERROR %s
+// RUN: %clang -c %s -### -target riscv64-linux-gnu -march=rv64gc_zve64x \
+// RUN:  -mrvv-vector-bits=A 2>&1 | FileCheck --check-prefix=CHECK-BAD-VALUE-ERROR %s
+// RUN: %clang -c %s -### -target riscv64-linux-gnu -march=rv64gc_zve64x \
+// RUN:  -mrvv-vector-bits=131072 2>&1 | FileCheck --check-prefix=CHECK-BAD-VALUE-ERROR %s
+// RUN: %clang -c %s -### -target riscv64-linux-gnu -march=rv64gc \
+// RUN:  -mrvv-vector-bits=zvl 2>&1 | FileCheck --check-prefix=CHECK-BAD-VALUE-ERROR %s
+// RUN: %clang -c %s -### -target riscv64-linux-gnu -march=rv64gcv \
+// RUN:  -mrvv-vector-bits=64 2>&1 | FileCheck --check-prefix=CHECK-BAD-VALUE-ERROR %s
+
+// CHECK-BAD-VALUE-ERROR: error: unsupported argument '{{.*}}' to option '-mrvv-vector-bits='
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -49,11 +49,14 @@
 #include "llvm/Support/CodeGen.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Compression.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
+#include "llvm/Support/RISCVISAInfo.h"
 #include "llvm/Support/YAMLParser.h"
+#include "llvm/TargetParser/RISCVTargetParser.h"
 #include <cctype>
 
 using namespace clang::driver;
@@ -2106,6 +2109,50 @@
     else
       CmdArgs.push_back(A->getValue());
   }
+
+  // Handle -mrvv-vector-bits=<bits>
+  if (Arg *A = Args.getLastArg(options::OPT_mrvv_vector_bits_EQ)) {
+    StringRef Val = A->getValue();
+    const Driver &D = getToolChain().getDriver();
+
+    // Get minimum VLen from march.
+    unsigned MinVLen = 0;
+    StringRef Arch = riscv::getRISCVArch(Args, Triple);
+    auto ISAInfo = llvm::RISCVISAInfo::parseArchString(
+        Arch, /*EnableExperimentalExtensions*/ true);
+    if (!ISAInfo) {
+      // Ignore parsing error.
+      consumeError(ISAInfo.takeError());
+    } else {
+      MinVLen = (*ISAInfo)->getMinVLen();
+    }
+
+    // If the value is "zvl", use MinVLen from march. Otherwise, try to parse
+    // as integer as long as we have a MinVLen.
+    unsigned Bits = 0;
+    if (Val.equals("zvl") && MinVLen >= llvm::RISCV::RVVBitsPerBlock) {
+      Bits = MinVLen;
+    } else if (!Val.getAsInteger(10, Bits)) {
+      // Only accept power of 2 values beteen RVVBitsPerBlock and 65536 that
+      // at least MinVLen.
+      if (Bits < MinVLen || Bits < llvm::RISCV::RVVBitsPerBlock ||
+          Bits > 65536 || !llvm::isPowerOf2_32(Bits))
+        Bits = 0;
+    }
+
+    // If we got a valid value try to use it.
+    if (Bits != 0) {
+      unsigned VScaleMin = Bits / llvm::RISCV::RVVBitsPerBlock;
+      CmdArgs.push_back(
+          Args.MakeArgString("-mvscale-max=" + llvm::Twine(VScaleMin)));
+      CmdArgs.push_back(
+          Args.MakeArgString("-mvscale-min=" + llvm::Twine(VScaleMin)));
+    } else if (!Val.equals("scalable")) {
+      // Handle the unsupported values passed to mrvv-vector-bits.
+      D.Diag(diag::err_drv_unsupported_option_argument)
+          << A->getSpelling() << Val;
+    }
+  }
 }
 
 void Clang::AddSparcTargetArgs(const ArgList &Args,
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -3582,6 +3582,10 @@
   HelpText<"Equivalent to -mcmodel=medium, compatible with RISC-V gcc.">;
 def menable_experimental_extensions : Flag<["-"], "menable-experimental-extensions">, Group<m_Group>,
   HelpText<"Enable use of experimental RISC-V extensions.">;
+def mrvv_vector_bits_EQ : Joined<["-"], "mrvv-vector-bits=">, Group<m_Group>,
+  HelpText<"Specify the size in bits of an RVV vector register. Defaults to the"
+           " vector length agnostic value of \"scalable\". Also accepts \"zvl\""
+           " to use the value implied by -march/-mcpu. (RISC-V only)">;
 
 def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_Group>,
   HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">;
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -841,6 +841,9 @@
 - Fix interaction of ``-mcpu`` and ``-march``, RISC-V backend will take the
   architecture extension union of ``-mcpu`` and ``-march`` before, and now will
   take architecture extensions from ``-march`` if both are given.
+- Added -rvv-vector-bits= option to give an upper bound on vector length. Valid
+  values are powers of 2 between 64 and 65536. We also accept "zvl" to use
+  the Zvl*b extension from -march/-mcpu to the be the upper and lower bound.
 
 X86 Support in Clang
 --------------------
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to