[clang][ARM] Enable --print-supported-extensions for ARM (#66083)

```
$ ./bin/clang --target=arm-linux-gnueabihf --print-supported-extensions
<...>
All available -march extensions for ARM

        crc
        crypto
        sha2
        aes
        dotprod
<...>
```

This follows the format set by RISC-V and AArch64. As for AArch64, ARM
doesn't have versioned extensions like RISC-V does. So there is only 1
column, which contains the name.

Any extension without a "feature" is hidden as these cannot be used with
-march.
This commit is contained in:
David Spickett 2023-09-13 10:10:57 +01:00 committed by GitHub
parent 11de4c724c
commit 99594ba30a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 45 additions and 2 deletions

View File

@ -5271,7 +5271,7 @@ def print_supported_cpus : Flag<["-", "--"], "print-supported-cpus">,
MarshallingInfoFlag<FrontendOpts<"PrintSupportedCPUs">>;
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<FrontendOpts<"PrintSupportedExtensions">>;
def : Flag<["-"], "mcpu=help">, Alias<print_supported_cpus>;
def : Flag<["-"], "mtune=help">, Alias<print_supported_cpus>;

View File

@ -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;

View File

@ -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

View File

@ -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 <cstdio>
#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.

View File

@ -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

View File

@ -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 <cctype>
@ -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";
}
}

View File

@ -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<AArch64::ExtensionBitset>> {};