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
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
--------------------
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)">;
#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;
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,
--- /dev/null
+// -----------------------------------------------------------------------------
+// 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='