diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/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 -------------------- diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/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, HelpText<"Enable use of experimental RISC-V extensions.">; +def mrvv_vector_bits_EQ : Joined<["-"], "mrvv-vector-bits=">, 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, 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 --- 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 using namespace clang::driver; @@ -2106,6 +2109,50 @@ else CmdArgs.push_back(A->getValue()); } + + // Handle -mrvv-vector-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 --- /dev/null +++ b/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='