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=' _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits