[clang] 089bfed - [RISCV][Driver] Add -mrvv-vector-bits= option similar to -msve-vector-bits=

Craig Topper via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 2 10:32:58 PST 2023


Author: Craig Topper
Date: 2023-02-02T10:32:14-08:00
New Revision: 089bfedfb828c2675f3cc57d6ecac1a87ca243a1

URL: https://github.com/llvm/llvm-project/commit/089bfedfb828c2675f3cc57d6ecac1a87ca243a1
DIFF: https://github.com/llvm/llvm-project/commit/089bfedfb828c2675f3cc57d6ecac1a87ca243a1.diff

LOG: [RISCV][Driver] Add -mrvv-vector-bits= option similar to -msve-vector-bits=

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.

I've added "scalable" from SVE to allow the option to be cancelled later on
command line. Though this name might make less sense for RISC-V since
the word "scalable" does not appear in the V spec. Maybe something like
"unknown" or "runtime" or "variable" would be better?

In addition to "scalable", 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.

Reviewed By: frasercrmck

Differential Revision: https://reviews.llvm.org/D142144

Added: 
    clang/test/Driver/riscv-rvv-vector-bits.c

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Driver/Options.td
    clang/lib/Driver/ToolChains/Clang.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4a86b379dda93..3ed971ec5847a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -157,6 +157,10 @@ LoongArch Support in Clang
 
 RISC-V Support in Clang
 -----------------------
+- Added ``-mrvv-vector-bits=`` option to give an upper and lower bound on vector
+  length. Valid values are powers of 2 between 64 and 65536. A value of 32
+  should eventually be supported. We also accept "zvl" to use the Zvl*b
+  extension from ``-march`` or ``-mcpu`` to the be the upper and lower bound.
 
 X86 Support in Clang
 --------------------

diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 2c7b594a60e3a..e91250e6b54c9 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3586,6 +3586,10 @@ def mcmodel_EQ_medany : Flag<["-"], "mcmodel=medany">, Group<m_Group>,
   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)">;

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 3d40e19c83a5e..c316de65d89a3 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/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 @@ void Clang::AddRISCVTargetArgs(const ArgList &Args,
     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,

diff  --git a/clang/test/Driver/riscv-rvv-vector-bits.c b/clang/test/Driver/riscv-rvv-vector-bits.c
new file mode 100644
index 0000000000000..2cc427502b149
--- /dev/null
+++ b/clang/test/Driver/riscv-rvv-vector-bits.c
@@ -0,0 +1,45 @@
+// -----------------------------------------------------------------------------
+// Tests for the -mrvv-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='


        


More information about the cfe-commits mailing list