diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index a5f5ca29053b4..2d42d05859bc1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5271,7 +5271,7 @@ def print_supported_cpus : Flag<["-", "--"], "print-supported-cpus">, MarshallingInfoFlag>; def print_supported_extensions : Flag<["-", "--"], "print-supported-extensions">, Visibility<[ClangOption, CC1Option, CLOption]>, - HelpText<"Print supported -march extensions (RISC-V and AArch64 only)">, + HelpText<"Print supported -march extensions (RISC-V, AArch64 and ARM only)">, MarshallingInfoFlag>; def : Flag<["-"], "mcpu=help">, Alias; def : Flag<["-"], "mtune=help">, Alias; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 9d30159b4b49c..84b8fc7685fed 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -4285,7 +4285,8 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, if (Arg *A = Args.getLastArg(Opt)) { if (Opt == options::OPT_print_supported_extensions && !C.getDefaultToolChain().getTriple().isRISCV() && - !C.getDefaultToolChain().getTriple().isAArch64()) { + !C.getDefaultToolChain().getTriple().isAArch64() && + !C.getDefaultToolChain().getTriple().isARM()) { C.getDriver().Diag(diag::err_opt_not_valid_on_target) << "--print-supported-extensions"; return; diff --git a/clang/test/Driver/print-supported-extensions.c b/clang/test/Driver/print-supported-extensions.c index dcb4328726ab5..8daf4d8a34b8a 100644 --- a/clang/test/Driver/print-supported-extensions.c +++ b/clang/test/Driver/print-supported-extensions.c @@ -9,6 +9,10 @@ // RUN: --print-supported-extensions 2>&1 | FileCheck %s --check-prefix RISCV %} // RISCV: All available -march extensions for RISC-V +// RUN: %if arm-registered-target %{ %clang --target=arm-linux-gnu \ +// RUN: --print-supported-extensions 2>&1 | FileCheck %s --check-prefix ARM %} +// ARM: All available -march extensions for ARM + // RUN: %if x86-registered-target %{ not %clang --target=x86_64-linux-gnu \ // RUN: --print-supported-extensions 2>&1 | FileCheck %s --check-prefix X86 %} // X86: error: option '--print-supported-extensions' cannot be specified on this target \ No newline at end of file diff --git a/clang/tools/driver/cc1_main.cpp b/clang/tools/driver/cc1_main.cpp index ed68a11d0191f..f0d7b5c3889dc 100644 --- a/clang/tools/driver/cc1_main.cpp +++ b/clang/tools/driver/cc1_main.cpp @@ -46,6 +46,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/TargetParser/AArch64TargetParser.h" +#include "llvm/TargetParser/ARMTargetParser.h" #include #ifdef CLANG_HAVE_RLIMITS @@ -202,6 +203,8 @@ static int PrintSupportedExtensions(std::string TargetStr) { llvm::riscvExtensionsHelp(); else if (MachineTriple.isAArch64()) llvm::AArch64::PrintSupportedExtensions(); + else if (MachineTriple.isARM()) + llvm::ARM::PrintSupportedExtensions(); else { // The option was already checked in Driver::HandleImmediateArgs, // so we do not expect to get here if we are not a supported architecture. diff --git a/llvm/include/llvm/TargetParser/ARMTargetParser.h b/llvm/include/llvm/TargetParser/ARMTargetParser.h index 9a81415681fdb..37a358d1fa415 100644 --- a/llvm/include/llvm/TargetParser/ARMTargetParser.h +++ b/llvm/include/llvm/TargetParser/ARMTargetParser.h @@ -259,6 +259,8 @@ StringRef computeDefaultTargetABI(const Triple &TT, StringRef CPU); /// string then the triple's arch name is used. StringRef getARMCPUForArch(const llvm::Triple &Triple, StringRef MArch = {}); +void PrintSupportedExtensions(); + } // namespace ARM } // namespace llvm diff --git a/llvm/lib/TargetParser/ARMTargetParser.cpp b/llvm/lib/TargetParser/ARMTargetParser.cpp index 785e9a4fe3fb9..7bf7914e9c531 100644 --- a/llvm/lib/TargetParser/ARMTargetParser.cpp +++ b/llvm/lib/TargetParser/ARMTargetParser.cpp @@ -13,6 +13,7 @@ #include "llvm/TargetParser/ARMTargetParser.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/ARMTargetParserCommon.h" #include "llvm/TargetParser/Triple.h" #include @@ -598,3 +599,12 @@ StringRef ARM::getARMCPUForArch(const llvm::Triple &Triple, StringRef MArch) { llvm_unreachable("invalid arch name"); } + +void ARM::PrintSupportedExtensions() { + outs() << "All available -march extensions for ARM\n\n"; + for (const auto &Ext : ARCHExtNames) { + // Extensions without a feature cannot be used with -march. + if (!Ext.Feature.empty()) + outs() << '\t' << Ext.Name << "\n"; + } +} diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp index d551eb985d373..8223f9f575135 100644 --- a/llvm/unittests/TargetParser/TargetParserTest.cpp +++ b/llvm/unittests/TargetParser/TargetParserTest.cpp @@ -1010,6 +1010,29 @@ TEST(TargetParserTest, getARMCPUForArch) { } } +TEST(TargetParserTest, ARMPrintSupportedExtensions) { + std::string expected = "All available -march extensions for ARM\n\n" + "\tcrc\n\tcrypto\n\tsha2"; + + outs().flush(); + testing::internal::CaptureStdout(); + ARM::PrintSupportedExtensions(); + outs().flush(); + std::string captured = testing::internal::GetCapturedStdout(); + + // Check that the start of the output is as expected. + EXPECT_EQ(0ULL, captured.find(expected)); + + // Should not include "none" or "invalid". + EXPECT_EQ(std::string::npos, captured.find("none")); + EXPECT_EQ(std::string::npos, captured.find("invalid")); + // Should not include anything that lacks a feature name. Checking a few here + // but not all as if one is hidden correctly the rest should be. + EXPECT_EQ(std::string::npos, captured.find("simd")); + EXPECT_EQ(std::string::npos, captured.find("maverick")); + EXPECT_EQ(std::string::npos, captured.find("xscale")); +} + class AArch64CPUTestFixture : public ::testing::TestWithParam< ARMCPUTestParams> {};