[clang] 1cbaf68 - [clang][AIX] Add option to control quadword lock free atomics ABI on AIX

Kai Luo via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 26 18:56:30 PDT 2022


Author: Kai Luo
Date: 2022-07-27T01:56:25Z
New Revision: 1cbaf681b0f1e7257e7e2a63d290a20216668f17

URL: https://github.com/llvm/llvm-project/commit/1cbaf681b0f1e7257e7e2a63d290a20216668f17
DIFF: https://github.com/llvm/llvm-project/commit/1cbaf681b0f1e7257e7e2a63d290a20216668f17.diff

LOG: [clang][AIX] Add option to control quadword lock free atomics ABI on AIX

We are supporting quadword lock free atomics on AIX. For the situation that users on AIX are using a libatomic that is lock-based for quadword types, we can't enable quadword lock free atomics by default on AIX in case user's new code and existing code accessing the same shared atomic quadword variable, we can't guarentee atomicity. So we need an option to enable quadword lock free atomics on AIX, thus we can build a quadword lock-free libatomic(also for advanced users considering atomic performance critical) for users to make the transition smooth.

Reviewed By: shchenz

Differential Revision: https://reviews.llvm.org/D127189

Added: 
    clang/test/Driver/aix-quadword-atomics-abi.c

Modified: 
    clang/include/clang/Basic/LangOptions.def
    clang/include/clang/Driver/Options.td
    clang/lib/Basic/Targets/PPC.cpp
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/lib/Frontend/CompilerInvocation.cpp
    clang/test/CodeGen/PowerPC/quadword-atomics.c
    clang/test/Driver/ppc-unsupported.c
    clang/test/Sema/atomic-ops.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index 6fb31c5655ab..ad366821f3cb 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -195,6 +195,7 @@ VALUE_LANGOPT(DoubleSize            , 32, 0, "width of double")
 VALUE_LANGOPT(LongDoubleSize        , 32, 0, "width of long double")
 LANGOPT(PPCIEEELongDouble            , 1, 0, "use IEEE 754 quadruple-precision for long double")
 LANGOPT(EnableAIXExtendedAltivecABI  , 1, 0, "__EXTABI__  predefined macro")
+LANGOPT(EnableAIXQuadwordAtomicsABI  , 1, 0, "Use 16-byte atomic lock free semantics")
 COMPATIBLE_VALUE_LANGOPT(PICLevel    , 2, 0, "__PIC__ level")
 COMPATIBLE_VALUE_LANGOPT(PIE         , 1, 0, "is pie")
 LANGOPT(ROPI                         , 1, 0, "Read-only position independence")

diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index b9c2e4d528e4..3cab37b21aaf 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3679,6 +3679,10 @@ def mabi_EQ_vec_extabi : Flag<["-"], "mabi=vec-extabi">, Group<m_Group>, Flags<[
   MarshallingInfoFlag<LangOpts<"EnableAIXExtendedAltivecABI">>;
 def mabi_EQ_vec_default : Flag<["-"], "mabi=vec-default">, Group<m_Group>, Flags<[CC1Option]>,
   HelpText<"Enable the default Altivec ABI on AIX (AIX only). Uses only volatile vector registers.">;
+def mabi_EQ_quadword_atomics : Flag<["-"], "mabi=quadword-atomics">,
+  Group<m_Group>, Flags<[CC1Option]>,
+  HelpText<"Enable quadword atomics ABI on AIX (AIX PPC64 only). Uses lqarx/stqcx. instructions.">,
+  MarshallingInfoFlag<LangOpts<"EnableAIXQuadwordAtomicsABI">>;
 def mvsx : Flag<["-"], "mvsx">, Group<m_ppc_Features_Group>;
 def mno_vsx : Flag<["-"], "mno-vsx">, Group<m_ppc_Features_Group>;
 def msecure_plt : Flag<["-"], "msecure-plt">, Group<m_ppc_Features_Group>;

diff  --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp
index 9120808e298d..ca01b44ae3a5 100644
--- a/clang/lib/Basic/Targets/PPC.cpp
+++ b/clang/lib/Basic/Targets/PPC.cpp
@@ -849,6 +849,9 @@ void PPCTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
                            ? &llvm::APFloat::IEEEquad()
                            : &llvm::APFloat::PPCDoubleDouble();
   Opts.IEEE128 = 1;
+  if (getTriple().isOSAIX() && Opts.EnableAIXQuadwordAtomicsABI &&
+      HasQuadwordAtomics)
+    MaxAtomicInlineWidth = 128;
 }
 
 ArrayRef<Builtin::Info> PPCTargetInfo::getTargetBuiltins() const {

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 3044c2d92d21..b62a025c5072 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5112,6 +5112,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
       CmdArgs.push_back("-mabi=vec-default");
   }
 
+  if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ_quadword_atomics)) {
+    if (!Triple.isOSAIX() || Triple.isPPC32())
+      D.Diag(diag::err_drv_unsupported_opt_for_target)
+        << A->getSpelling() << RawTriple.str();
+    CmdArgs.push_back("-mabi=quadword-atomics");
+  }
+
   if (Arg *A = Args.getLastArg(options::OPT_mlong_double_128)) {
     // Emit the unsupported option error until the Clang's library integration
     // support for 128-bit long double is available for AIX.

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 48cd6a394107..2dd96e68bb92 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1926,6 +1926,12 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
     Opts.EnableAIXExtendedAltivecABI = O.matches(OPT_mabi_EQ_vec_extabi);
   }
 
+  if (Arg *A = Args.getLastArg(OPT_mabi_EQ_quadword_atomics)) {
+    if (!T.isOSAIX() || T.isPPC32())
+      Diags.Report(diag::err_drv_unsupported_opt_for_target)
+        << A->getSpelling() << T.str();
+  }
+
   bool NeedLocTracking = false;
 
   if (!Opts.OptRecordFile.empty())

diff  --git a/clang/test/CodeGen/PowerPC/quadword-atomics.c b/clang/test/CodeGen/PowerPC/quadword-atomics.c
index e8ea687ba534..e494d6f785f6 100644
--- a/clang/test/CodeGen/PowerPC/quadword-atomics.c
+++ b/clang/test/CodeGen/PowerPC/quadword-atomics.c
@@ -1,9 +1,15 @@
 // RUN: %clang_cc1 -no-opaque-pointers -Werror -Wno-atomic-alignment -triple powerpc64le-linux-gnu \
-// RUN:   -target-cpu pwr8 -emit-llvm -o - %s | FileCheck %s --check-prefix=PPC64-PWR8
+// RUN:   -target-cpu pwr8 -emit-llvm -o - %s | FileCheck %s --check-prefix=PPC64-QUADWORD-ATOMICS
 // RUN: %clang_cc1 -no-opaque-pointers -Werror -Wno-atomic-alignment -triple powerpc64le-linux-gnu \
 // RUN:   -emit-llvm -o - %s | FileCheck %s --check-prefix=PPC64
 // RUN: %clang_cc1 -no-opaque-pointers -Werror -Wno-atomic-alignment -triple powerpc64-unknown-aix \
 // RUN:   -target-cpu pwr7 -emit-llvm -o - %s | FileCheck %s --check-prefix=PPC64
+// RUN: %clang_cc1 -no-opaque-pointers -Werror -Wno-atomic-alignment -triple powerpc64-unknown-aix \
+// RUN:   -target-cpu pwr8 -emit-llvm -o - %s | FileCheck %s --check-prefix=PPC64
+// RUN: %clang_cc1 -no-opaque-pointers -Werror -Wno-atomic-alignment -triple powerpc64-unknown-aix \
+// RUN:   -mabi=quadword-atomics -target-cpu pwr8 -emit-llvm -o - %s | FileCheck %s \
+// RUN:   --check-prefix=PPC64-QUADWORD-ATOMICS
+
 
 typedef struct {
   char x[16];
@@ -13,8 +19,8 @@ typedef _Atomic(Q) AtomicQ;
 
 typedef __int128_t int128_t;
 
-// PPC64-PWR8-LABEL: @test_load(
-// PPC64-PWR8:    [[TMP3:%.*]] = load atomic i128, i128* [[TMP1:%.*]] acquire, align 16
+// PPC64-QUADWORD-ATOMICS-LABEL: @test_load(
+// PPC64-QUADWORD-ATOMICS:    [[TMP3:%.*]] = load atomic i128, i128* [[TMP1:%.*]] acquire, align 16
 //
 // PPC64-LABEL: @test_load(
 // PPC64:    call void @__atomic_load(i64 noundef 16, i8* noundef [[TMP3:%.*]], i8* noundef [[TMP4:%.*]], i32 noundef signext 2)
@@ -24,8 +30,8 @@ Q test_load(AtomicQ *ptr) {
   return __c11_atomic_load(ptr, __ATOMIC_ACQUIRE);
 }
 
-// PPC64-PWR8-LABEL: @test_store(
-// PPC64-PWR8:    store atomic i128 [[TMP6:%.*]], i128* [[TMP4:%.*]] release, align 16
+// PPC64-QUADWORD-ATOMICS-LABEL: @test_store(
+// PPC64-QUADWORD-ATOMICS:    store atomic i128 [[TMP6:%.*]], i128* [[TMP4:%.*]] release, align 16
 //
 // PPC64-LABEL: @test_store(
 // PPC64:    call void @__atomic_store(i64 noundef 16, i8* noundef [[TMP6:%.*]], i8* noundef [[TMP7:%.*]], i32 noundef signext 3)
@@ -35,8 +41,8 @@ void test_store(Q val, AtomicQ *ptr) {
   __c11_atomic_store(ptr, val, __ATOMIC_RELEASE);
 }
 
-// PPC64-PWR8-LABEL: @test_add(
-// PPC64-PWR8:    [[TMP3:%.*]] = atomicrmw add i128* [[TMP0:%.*]], i128 [[TMP2:%.*]] monotonic, align 16
+// PPC64-QUADWORD-ATOMICS-LABEL: @test_add(
+// PPC64-QUADWORD-ATOMICS:    [[TMP3:%.*]] = atomicrmw add i128* [[TMP0:%.*]], i128 [[TMP2:%.*]] monotonic, align 16
 //
 // PPC64-LABEL: @test_add(
 // PPC64:    [[CALL:%.*]] = call i128 @__atomic_fetch_add_16(i8* noundef [[TMP2:%.*]], i128 noundef [[TMP3:%.*]], i32 noundef signext 0)
@@ -46,8 +52,8 @@ void test_add(_Atomic(int128_t) *ptr, int128_t x) {
   __c11_atomic_fetch_add(ptr, x, __ATOMIC_RELAXED);
 }
 
-// PPC64-PWR8-LABEL: @test_xchg(
-// PPC64-PWR8:    [[TMP8:%.*]] = atomicrmw xchg i128* [[TMP4:%.*]], i128 [[TMP7:%.*]] seq_cst, align 16
+// PPC64-QUADWORD-ATOMICS-LABEL: @test_xchg(
+// PPC64-QUADWORD-ATOMICS:    [[TMP8:%.*]] = atomicrmw xchg i128* [[TMP4:%.*]], i128 [[TMP7:%.*]] seq_cst, align 16
 //
 // PPC64-LABEL: @test_xchg(
 // PPC64:    call void @__atomic_exchange(i64 noundef 16, i8* noundef [[TMP7:%.*]], i8* noundef [[TMP8:%.*]], i8* noundef [[TMP9:%.*]], i32 noundef signext 5)
@@ -57,8 +63,8 @@ Q test_xchg(AtomicQ *ptr, Q new) {
   return __c11_atomic_exchange(ptr, new, __ATOMIC_SEQ_CST);
 }
 
-// PPC64-PWR8-LABEL: @test_cmpxchg(
-// PPC64-PWR8:    [[TMP10:%.*]] = cmpxchg i128* [[TMP5:%.*]], i128 [[TMP8:%.*]], i128 [[TMP9:%.*]] seq_cst monotonic, align 16
+// PPC64-QUADWORD-ATOMICS-LABEL: @test_cmpxchg(
+// PPC64-QUADWORD-ATOMICS:    [[TMP10:%.*]] = cmpxchg i128* [[TMP5:%.*]], i128 [[TMP8:%.*]], i128 [[TMP9:%.*]] seq_cst monotonic, align 16
 //
 // PPC64-LABEL: @test_cmpxchg(
 // PPC64:    [[CALL:%.*]] = call zeroext i1 @__atomic_compare_exchange(i64 noundef 16, i8* noundef [[TMP8:%.*]], i8* noundef [[TMP9:%.*]], i8* noundef [[TMP10:%.*]], i32 noundef signext 5, i32 noundef signext 0)
@@ -68,8 +74,8 @@ int test_cmpxchg(AtomicQ *ptr, Q *cmp, Q new) {
   return __c11_atomic_compare_exchange_strong(ptr, cmp, new, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
 }
 
-// PPC64-PWR8-LABEL: @test_cmpxchg_weak(
-// PPC64-PWR8:    [[TMP10:%.*]] = cmpxchg weak i128* [[TMP5:%.*]], i128 [[TMP8:%.*]], i128 [[TMP9:%.*]] seq_cst monotonic, align 16
+// PPC64-QUADWORD-ATOMICS-LABEL: @test_cmpxchg_weak(
+// PPC64-QUADWORD-ATOMICS:    [[TMP10:%.*]] = cmpxchg weak i128* [[TMP5:%.*]], i128 [[TMP8:%.*]], i128 [[TMP9:%.*]] seq_cst monotonic, align 16
 //
 // PPC64-LABEL: @test_cmpxchg_weak(
 // PPC64:    [[CALL:%.*]] = call zeroext i1 @__atomic_compare_exchange(i64 noundef 16, i8* noundef [[TMP8:%.*]], i8* noundef [[TMP9:%.*]], i8* noundef [[TMP10:%.*]], i32 noundef signext 5, i32 noundef signext 0)
@@ -79,8 +85,8 @@ int test_cmpxchg_weak(AtomicQ *ptr, Q *cmp, Q new) {
   return __c11_atomic_compare_exchange_weak(ptr, cmp, new, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
 }
 
-// PPC64-PWR8-LABEL: @is_lock_free(
-// PPC64-PWR8:    ret i32 1
+// PPC64-QUADWORD-ATOMICS-LABEL: @is_lock_free(
+// PPC64-QUADWORD-ATOMICS:    ret i32 1
 //
 // PPC64-LABEL: @is_lock_free(
 // PPC64:    [[CALL:%.*]] = call zeroext i1 @__atomic_is_lock_free(i64 noundef 16, i8* noundef null)

diff  --git a/clang/test/Driver/aix-quadword-atomics-abi.c b/clang/test/Driver/aix-quadword-atomics-abi.c
new file mode 100644
index 000000000000..56c3e815bfd2
--- /dev/null
+++ b/clang/test/Driver/aix-quadword-atomics-abi.c
@@ -0,0 +1,11 @@
+// RUN:  %clang -### -target powerpc-unknown-aix -S %s 2>&1 | FileCheck %s
+// RUN:  %clang -### -target powerpc64-unknown-aix -S %s 2>&1 | FileCheck %s
+// RUN:  %clang -### -target powerpc-unknown-aix -mabi=quadword-atomics -S \
+// RUN:    %s 2>&1 | FileCheck --check-prefix=CHECK-UNSUPPORTED-TARGET %s
+// RUN:  %clang -### -target powerpc64-unknown-aix -mabi=quadword-atomics -S \
+// RUN:    %s 2>&1 | FileCheck %s --check-prefix=CHECK-QUADWORD-ATOMICS
+//
+// CHECK-UNSUPPORTED-TARGET: unsupported option '-mabi=quadword-atomics' for target 'powerpc-unknown-aix'
+// CHECK-NOT: "-mabi=quadword-atomics"
+// CHECK-QUADWORD-ATOMICS: "-cc1"
+// CHECK-QUADWORD-ATOMICS-SAME: "-mabi=quadword-atomics"

diff  --git a/clang/test/Driver/ppc-unsupported.c b/clang/test/Driver/ppc-unsupported.c
index 84760c8c435b..8361edb8e1d7 100644
--- a/clang/test/Driver/ppc-unsupported.c
+++ b/clang/test/Driver/ppc-unsupported.c
@@ -7,4 +7,14 @@
 // RUN:   -c %s 2>&1 | FileCheck %s
 // RUN: not %clang -target powerpc64le-unknown-linux -msvr4-struct-return \
 // RUN:   -c %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64-unknown-freebsd -mabi=quadword-atomics \
+// RUN:   -c %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64-unknown-linux -mabi=quadword-atomics \
+// RUN:   -c %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-unknown-linux -mabi=quadword-atomics \
+// RUN:   -c %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc-unknown-unknown -mabi=quadword-atomics \
+// RUN:   -c %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc-unknown-aix -mabi=quadword-atomics \
+// RUN:   -c %s 2>&1 | FileCheck %s
 // CHECK: unsupported option

diff  --git a/clang/test/Sema/atomic-ops.c b/clang/test/Sema/atomic-ops.c
index 30a4299fe31d..6ac47e12f244 100644
--- a/clang/test/Sema/atomic-ops.c
+++ b/clang/test/Sema/atomic-ops.c
@@ -10,6 +10,12 @@
 // RUN: %clang_cc1 %s -verify -fgnuc-version=4.2.1 -ffreestanding \
 // RUN:   -fsyntax-only -triple=powerpc64le-linux-gnu -std=c11 \
 // RUN:   -target-cpu pwr8 -DPPC64_PWR8
+// RUN: %clang_cc1 %s -verify -fgnuc-version=4.2.1 -ffreestanding \
+// RUN:   -fsyntax-only -triple=powerpc64-unknown-aix -std=c11 \
+// RUN:   -target-cpu pwr8
+// RUN: %clang_cc1 %s -verify -fgnuc-version=4.2.1 -ffreestanding \
+// RUN:   -fsyntax-only -triple=powerpc64-unknown-aix -std=c11 \
+// RUN:   -mabi=quadword-atomics -target-cpu pwr8 -DPPC64_PWR8
 
 // Basic parsing/Sema tests for __c11_atomic_*
 


        


More information about the cfe-commits mailing list