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 @@ -6441,6 +6441,12 @@ 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 @@ -836,6 +836,21 @@ getTriple().isMusl() || getSanitizerArgs().requiresPIE(); } +bool Linux::IsAArch64OutlineAtomicsDefault(const ArgList &Args) const { + if (!getTriple().isAArch64()) + return false; + // Outline atomics for AArch64 are supported by compiler-rt + // and libgcc since 9.3.1 + if (GetRuntimeLibType(Args) == ToolChain::RLT_Libgcc) { + const GCCVersion &Ver = GCCInstallation.getVersion(); + if (Ver.isOlderThan(9, 3, 1)) + return false; + } else if (GetRuntimeLibType(Args) != ToolChain::RLT_CompilerRT) { + return false; + } + return true; +} + bool Linux::isNoExecStackDefault() const { return getTriple().isAndroid(); }