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 @@ -6435,6 +6435,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(); } diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/lib/Target/AArch64/AArch64.td @@ -1084,6 +1084,7 @@ FeatureFPARMv8, FeatureFuseAES, FeatureNEON, + FeatureOutlineAtomics, FeaturePerfMon, FeaturePostRAScheduler, // ETE and TRBE are future architecture extensions. We temporarily enable them diff --git a/llvm/test/CodeGen/AArch64/arm64_32-atomics.ll b/llvm/test/CodeGen/AArch64/arm64_32-atomics.ll --- a/llvm/test/CodeGen/AArch64/arm64_32-atomics.ll +++ b/llvm/test/CodeGen/AArch64/arm64_32-atomics.ll @@ -1,5 +1,5 @@ -; RUN: llc -mtriple=arm64_32-apple-ios7.0 -o - %s | FileCheck %s -; RUN: llc -mtriple=arm64_32-apple-ios7.0 -mattr=+outline-atomics -o - %s | FileCheck %s -check-prefix=OUTLINE-ATOMICS +; RUN: llc -mtriple=arm64_32-apple-ios7.0 -mattr=-outline-atomics -o - %s | FileCheck %s +; RUN: llc -mtriple=arm64_32-apple-ios7.0 -o - %s | FileCheck %s -check-prefix=OUTLINE-ATOMICS define i8 @test_load_8(i8* %addr) { ; CHECK-LABAL: test_load_8: diff --git a/llvm/test/CodeGen/AArch64/atomic-ops-not-barriers.ll b/llvm/test/CodeGen/AArch64/atomic-ops-not-barriers.ll --- a/llvm/test/CodeGen/AArch64/atomic-ops-not-barriers.ll +++ b/llvm/test/CodeGen/AArch64/atomic-ops-not-barriers.ll @@ -1,5 +1,5 @@ -; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s -; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs -mattr=+outline-atomics < %s | FileCheck %s --check-prefix=OUTLINE-ATOMICS +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs -mattr=-outline-atomics < %s | FileCheck %s +; RUN: llc -mtriple=aarch64-none-linux-gnu -verify-machineinstrs < %s | FileCheck %s --check-prefix=OUTLINE-ATOMICS define i32 @foo(i32* %var, i1 %cond) { ; OUTLINE-ATOMICS: bl __aarch64_ldadd4_relax diff --git a/llvm/test/CodeGen/AArch64/atomic-ops.ll b/llvm/test/CodeGen/AArch64/atomic-ops.ll --- a/llvm/test/CodeGen/AArch64/atomic-ops.ll +++ b/llvm/test/CodeGen/AArch64/atomic-ops.ll @@ -1,6 +1,6 @@ -; RUN: llc -mtriple=aarch64-none-linux-gnu -disable-post-ra -verify-machineinstrs < %s | FileCheck %s -; RUN: llc -mtriple=aarch64-none-linux-gnu -disable-post-ra -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK-REG -; RUN: llc -mtriple=aarch64-none-linux-gnu -disable-post-ra -verify-machineinstrs -mattr=+outline-atomics < %s | FileCheck %s --check-prefix=OUTLINE_ATOMICS +; RUN: llc -mtriple=aarch64-none-linux-gnu -disable-post-ra -verify-machineinstrs -mattr=-outline-atomics < %s | FileCheck %s +; RUN: llc -mtriple=aarch64-none-linux-gnu -disable-post-ra -verify-machineinstrs -mattr=-outline-atomics < %s | FileCheck %s --check-prefix=CHECK-REG +; RUN: llc -mtriple=aarch64-none-linux-gnu -disable-post-ra -verify-machineinstrs < %s | FileCheck %s --check-prefix=OUTLINE_ATOMICS ; Point of CHECK-REG is to make sure UNPREDICTABLE instructions aren't created diff --git a/llvm/test/CodeGen/AArch64/cmpxchg-O0.ll b/llvm/test/CodeGen/AArch64/cmpxchg-O0.ll --- a/llvm/test/CodeGen/AArch64/cmpxchg-O0.ll +++ b/llvm/test/CodeGen/AArch64/cmpxchg-O0.ll @@ -1,5 +1,5 @@ -; RUN: llc -verify-machineinstrs -mtriple=aarch64-linux-gnu -O0 -fast-isel=0 -global-isel=false %s -o - | FileCheck -enable-var-scope %s -; RUN: llc -verify-machineinstrs -mtriple=aarch64-linux-gnu -O0 -fast-isel=0 -global-isel=false -mattr=+outline-atomics %s -o - | FileCheck -enable-var-scope %s --check-prefix=OUTLINE-ATOMICS +; RUN: llc -verify-machineinstrs -mtriple=aarch64-linux-gnu -O0 -fast-isel=0 -global-isel=false -mattr=-outline-atomics %s -o - | FileCheck -enable-var-scope %s +; RUN: llc -verify-machineinstrs -mtriple=aarch64-linux-gnu -O0 -fast-isel=0 -global-isel=false %s -o - | FileCheck -enable-var-scope %s --check-prefix=OUTLINE-ATOMICS define { i8, i1 } @test_cmpxchg_8(i8* %addr, i8 %desired, i8 %new) nounwind { ; OUTLINE-ATOMICS: bl __aarch64_cas1_acq_rel diff --git a/llvm/test/CodeGen/AArch64/cmpxchg-idioms.ll b/llvm/test/CodeGen/AArch64/cmpxchg-idioms.ll --- a/llvm/test/CodeGen/AArch64/cmpxchg-idioms.ll +++ b/llvm/test/CodeGen/AArch64/cmpxchg-idioms.ll @@ -1,5 +1,5 @@ -; RUN: llc -mtriple=aarch64-apple-ios7.0 -o - %s | FileCheck %s -; RUN: llc -mtriple=aarch64-apple-ios7.0 -mattr=+outline-atomics -o - %s | FileCheck %s --check-prefix=OUTLINE-ATOMICS +; RUN: llc -mtriple=aarch64-apple-ios7.0 -mattr=-outline-atomics -o - %s | FileCheck %s +; RUN: llc -mtriple=aarch64-apple-ios7.0 -o - %s | FileCheck %s --check-prefix=OUTLINE-ATOMICS define i32 @test_return(i32* %p, i32 %oldval, i32 %newval) { ; OUTLINE-ATOMICS: bl ___aarch64_cas4_acq_rel diff --git a/llvm/test/Transforms/AtomicExpand/AArch64/expand-atomicrmw-xchg-fp.ll b/llvm/test/Transforms/AtomicExpand/AArch64/expand-atomicrmw-xchg-fp.ll --- a/llvm/test/Transforms/AtomicExpand/AArch64/expand-atomicrmw-xchg-fp.ll +++ b/llvm/test/Transforms/AtomicExpand/AArch64/expand-atomicrmw-xchg-fp.ll @@ -1,6 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -mtriple=aarch64-- -atomic-expand %s | FileCheck %s -; RUN: opt -S -mtriple=aarch64-- -mattr=+outline-atomics -atomic-expand %s | FileCheck %s --check-prefix=OUTLINE-ATOMICS +; RUN: opt -S -mtriple=aarch64-- -mattr=-outline-atomics -atomic-expand %s | FileCheck %s +; RUN: opt -S -mtriple=aarch64-- -atomic-expand %s | FileCheck %s --check-prefix=OUTLINE-ATOMICS define void @atomic_swap_f16(half* %ptr, half %val) nounwind { ; CHECK-LABEL: @atomic_swap_f16(