diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -456,6 +456,12 @@ /// by default. virtual bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const; + /// Test whether this toolchain supports outline atomics by default. + virtual bool + IsAArch64OutlineAtomicsDefault(const llvm::opt::ArgList &Args) const { + return false; + } + /// Test whether this toolchain defaults to PIC. virtual bool isPICDefault() const = 0; 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 @@ -6481,6 +6481,10 @@ CmdArgs.push_back("-target-feature"); CmdArgs.push_back("-outline-atomics"); } + } else if (Triple.isAArch64() && + getToolChain().IsAArch64OutlineAtomicsDefault(Args)) { + CmdArgs.push_back("-target-feature"); + CmdArgs.push_back("+outline-atomics"); } if (Args.hasFlag(options::OPT_faddrsig, options::OPT_fno_addrsig, diff --git a/clang/lib/Driver/ToolChains/Linux.h b/clang/lib/Driver/ToolChains/Linux.h --- a/clang/lib/Driver/ToolChains/Linux.h +++ b/clang/lib/Driver/ToolChains/Linux.h @@ -36,6 +36,8 @@ void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; CXXStdlibType GetDefaultCXXStdlibType() const override; + bool + IsAArch64OutlineAtomicsDefault(const llvm::opt::ArgList &Args) const override; bool isPIEDefault() const override; bool isNoExecStackDefault() const override; bool IsMathErrnoDefault() const override; diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -845,6 +845,19 @@ getTriple().isMusl() || getSanitizerArgs().requiresPIE(); } +bool Linux::IsAArch64OutlineAtomicsDefault(const ArgList &Args) const { + // Outline atomics for AArch64 are supported by compiler-rt + // and libgcc since 9.3.1 + assert(getTriple().isAArch64() && "expected AArch64 target!"); + ToolChain::RuntimeLibType RtLib = GetRuntimeLibType(Args); + if (RtLib == ToolChain::RLT_CompilerRT) + return true; + assert(RtLib == ToolChain::RLT_Libgcc && "unexpected runtime library type!"); + if (GCCInstallation.getVersion().isOlderThan(9, 3, 1)) + return false; + return true; +} + bool Linux::isNoExecStackDefault() const { return getTriple().isAndroid(); } diff --git a/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-10/lib/gcc/aarch64-unknown-linux-gnu/10/crtbegin.o b/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-10/lib/gcc/aarch64-unknown-linux-gnu/10/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-10/lib/gcc/aarch64-unknown-linux-gnu/10/libgcc.a b/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-10/lib/gcc/aarch64-unknown-linux-gnu/10/libgcc.a new file mode 100644 diff --git a/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-7.5.0/lib/gcc/aarch64-unknown-linux-gnu/7.5.0/crtbegin.o b/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-7.5.0/lib/gcc/aarch64-unknown-linux-gnu/7.5.0/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-7.5.0/lib/gcc/aarch64-unknown-linux-gnu/7.5.0/libgcc.a b/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-7.5.0/lib/gcc/aarch64-unknown-linux-gnu/7.5.0/libgcc.a new file mode 100644 diff --git a/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-9.3.0/lib/gcc/aarch64-unknown-linux-gnu/9.3.0/crtbegin.o b/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-9.3.0/lib/gcc/aarch64-unknown-linux-gnu/9.3.0/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-9.3.0/lib/gcc/aarch64-unknown-linux-gnu/9.3.0/libgcc.a b/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-9.3.0/lib/gcc/aarch64-unknown-linux-gnu/9.3.0/libgcc.a new file mode 100644 diff --git a/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-9.3.1/lib/gcc/aarch64-unknown-linux-gnu/9.3.1/crtbegin.o b/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-9.3.1/lib/gcc/aarch64-unknown-linux-gnu/9.3.1/crtbegin.o new file mode 100644 diff --git a/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-9.3.1/lib/gcc/aarch64-unknown-linux-gnu/9.3.1/libgcc.a b/clang/test/Driver/Inputs/aarch64-linux-gnu-tree/gcc-9.3.1/lib/gcc/aarch64-unknown-linux-gnu/9.3.1/libgcc.a new file mode 100644 diff --git a/clang/test/Driver/aarch64-features.c b/clang/test/Driver/aarch64-features.c --- a/clang/test/Driver/aarch64-features.c +++ b/clang/test/Driver/aarch64-features.c @@ -6,3 +6,60 @@ // The AArch64 PCS states that chars should be unsigned. // CHECK: fno-signed-char +// Check for AArch64 out-of-line atomics default settings. +// RUN: %clang -target aarch64-linux-android -rtlib=compiler-rt \ +// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-OUTLINE-ATOMICS-ON %s + +// RUN: %clang -target aarch64-linux-gnu -rtlib=compiler-rt \ +// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-OUTLINE-ATOMICS-ON %s + +// RUN: %clang -target arm64-unknown-linux -rtlib=compiler-rt \ +// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-OUTLINE-ATOMICS-ON %s + +// RUN: %clang -target aarch64--none-eabi -rtlib=compiler-rt \ +// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-OUTLINE-ATOMICS-OFF %s + +// RUN: %clang -target aarch64-apple-darwin -rtlib=compiler-rt \ +// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-OUTLINE-ATOMICS-OFF %s + +// RUN: %clang -target aarch64-windows-gnu -rtlib=compiler-rt \ +// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-OUTLINE-ATOMICS-OFF %s + +// RUN: %clang -target aarch64-unknown-openbsd -rtlib=compiler-rt \ +// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-OUTLINE-ATOMICS-OFF %s + +// RUN: %clang -target aarch64-linux-gnu -rtlib=libgcc \ +// RUN: --gcc-toolchain=%S/Inputs/aarch64-linux-gnu-tree/gcc-10 \ +// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-OUTLINE-ATOMICS-ON %s + +// RUN: %clang -target aarch64-linux-gnu -rtlib=libgcc \ +// RUN: --gcc-toolchain=%S/Inputs/aarch64-linux-gnu-tree/gcc-7.5.0 \ +// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-OUTLINE-ATOMICS-OFF %s + +// RUN: %clang -target aarch64-linux-gnu -rtlib=libgcc \ +// RUN: --gcc-toolchain=%S/Inputs/aarch64-linux-gnu-tree/gcc-9.3.1 \ +// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-OUTLINE-ATOMICS-ON %s + +// RUN: %clang -target aarch64-linux-gnu -rtlib=libgcc \ +// RUN: --gcc-toolchain=%S/Inputs/aarch64-linux-gnu-tree/gcc-9.3.0 \ +// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-OUTLINE-ATOMICS-OFF %s + +// RUN: %clang -target arm64-linux -rtlib=compiler-rt -mno-outline-atomics \ +// RUN: -### -c %s 2>&1 | FileCheck \ +// RUN: -check-prefixes=CHECK-OUTLINE-ATOMICS-OFF,CHECK-NO-OUTLINE-ATOMICS %s + +// RUN: %clang -target aarch64-linux-gnu -rtlib=libgcc -mno-outline-atomics \ +// RUN: --gcc-toolchain=%S/Inputs/aarch64-linux-gnu-tree/gcc-10 \ +// RUN: -### -c %s 2>&1 | FileCheck \ +// RUN: -check-prefixes=CHECK-OUTLINE-ATOMICS-OFF,CHECK-NO-OUTLINE-ATOMICS %s + +// RUN: %clang -target aarch64-apple-darwin -rtlib=compiler-rt -moutline-atomics \ +// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-OUTLINE-ATOMICS-ON %s + +// RUN: %clang -target aarch64-windows-gnu -rtlib=libgcc -moutline-atomics \ +// RUN: --gcc-toolchain=%S/Inputs/aarch64-linux-gnu-tree/gcc-7.5.0 \ +// RUN: -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-OUTLINE-ATOMICS-ON %s + +// CHECK-OUTLINE-ATOMICS-ON: "-target-feature" "+outline-atomics" +// CHECK-OUTLINE-ATOMICS-OFF-NOT: "-target-feature" "+outline-atomics" +// CHECK-NO-OUTLINE-ATOMICS: "-target-feature" "-outline-atomics"