diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -2816,7 +2816,8 @@ "invalid SVE vector size '%0', must match value set by " "'-msve-vector-bits' ('%1')">; def err_attribute_arm_feature_sve_bits_unsupported : Error< - "%0 is not supported when '-msve-vector-bits=' is not specified">; + "%0 is only supported when '-msve-vector-bits=' is specified with a " + "value of 128, 256, 512, 1024 or 2048.">; def err_attribute_requires_positive_integer : Error< "%0 attribute requires a %select{positive|non-negative}1 " "integral compile time constant expression">; 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 @@ -2346,8 +2346,9 @@ def msve_vector_bits_EQ : Joined<["-"], "msve-vector-bits=">, Group, Flags<[DriverOption,CC1Option]>, - HelpText<"Set the size of fixed-length SVE vectors in bits.">, - Values<"128,256,512,1024,2048">; + HelpText<"Specify the size in bits of an SVE vector register. Defaults to the" + " vector length agnostic value of \"scalable\". (AArch64 only)">, + Values<"128,256,512,1024,2048,scalable">; def msign_return_address_EQ : Joined<["-"], "msign-return-address=">, Flags<[CC1Option]>, Group, Values<"none,all,non-leaf">, diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -370,8 +370,8 @@ V8_6Pos = Features.insert(std::next(V8_6Pos), {"+i8mm", "+bf16"}); bool HasSve = llvm::is_contained(Features, "+sve"); - // -msve_vector_bits= flag is valid only if SVE is enabled. - if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) + // -msve-vector-bits= flag is valid only if SVE is enabled. + if (Args.hasArg(options::OPT_msve_vector_bits_EQ)) if (!HasSve) D.Diag(diag::err_drv_invalid_sve_vector_bits); 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 @@ -1720,15 +1720,15 @@ if (Arg *A = Args.getLastArg(options::OPT_msve_vector_bits_EQ)) { StringRef Val = A->getValue(); const Driver &D = getToolChain().getDriver(); - if (!Val.equals("128") && !Val.equals("256") && !Val.equals("512") && - !Val.equals("1024") && !Val.equals("2048")) { + if (Val.equals("128") || Val.equals("256") || Val.equals("512") || + Val.equals("1024") || Val.equals("2048")) + CmdArgs.push_back( + Args.MakeArgString(llvm::Twine("-msve-vector-bits=") + Val)); + // Silently drop requests for vector-length agnostic code as it's implied. + else if (!Val.equals("scalable")) // Handle the unsupported values passed to msve-vector-bits. D.Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName() << Val; - } else if (A->getOption().matches(options::OPT_msve_vector_bits_EQ)) { - CmdArgs.push_back( - Args.MakeArgString(llvm::Twine("-msve-vector-bits=") + Val)); - } } } diff --git a/clang/test/Driver/aarch64-sve-vector-bits.c b/clang/test/Driver/aarch64-sve-vector-bits.c --- a/clang/test/Driver/aarch64-sve-vector-bits.c +++ b/clang/test/Driver/aarch64-sve-vector-bits.c @@ -12,12 +12,15 @@ // RUN: -msve-vector-bits=1024 2>&1 | FileCheck --check-prefix=CHECK-1024 %s // RUN: %clang -c %s -### -target aarch64-none-linux-gnu -march=armv8-a+sve \ // RUN: -msve-vector-bits=2048 2>&1 | FileCheck --check-prefix=CHECK-2048 %s +// RUN: %clang -c %s -### -target aarch64-none-linux-gnu -march=armv8-a+sve \ +// RUN: -msve-vector-bits=scalable 2>&1 | FileCheck --check-prefix=CHECK-SCALABLE %s // CHECK-128: "-msve-vector-bits=128" // CHECK-256: "-msve-vector-bits=256" // CHECK-512: "-msve-vector-bits=512" // CHECK-1024: "-msve-vector-bits=1024" // CHECK-2048: "-msve-vector-bits=2048" +// CHECK-SCALABLE-NOT: "-msve-vector-bits= // Bail out if -msve-vector-bits is specified without SVE enabled // ----------------------------------------------------------------------------- @@ -47,11 +50,13 @@ // ----------------------------------------------------------------------------- // RUN: not %clang -c %s -o /dev/null -target aarch64-none-linux-gnu \ // RUN: -march=armv8-a+sve 2>&1 | FileCheck --check-prefix=CHECK-NO-FLAG-ERROR %s +// RUN: not %clang -c %s -o /dev/null -target aarch64-none-linux-gnu \ +// RUN: -march=armv8-a+sve -msve-vector-bits=scalable 2>&1 | FileCheck --check-prefix=CHECK-NO-FLAG-ERROR %s typedef __SVInt32_t svint32_t; typedef svint32_t noflag __attribute__((arm_sve_vector_bits(256))); -// CHECK-NO-FLAG-ERROR: error: 'arm_sve_vector_bits' is not supported when '-msve-vector-bits=' is not specified +// CHECK-NO-FLAG-ERROR: error: 'arm_sve_vector_bits' is only supported when '-msve-vector-bits=' is specified with a value of 128, 256, 512, 1024 or 2048 // Error if attribute vector size != -msve-vector-bits // -----------------------------------------------------------------------------