diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -74,6 +74,7 @@ bool HasP10Vector = false; bool HasPCRelativeMemops = false; bool HasPrefixInstrs = false; + bool HasQuadwordAtomics = false; protected: std::string ABI; @@ -437,6 +438,12 @@ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; } + void setMaxAtomicWidth() override { + // FIXME: Current only support quadword inline atomics on AIX. + if (getTriple().isOSAIX() && hasFeature("quadword-atomics")) + MaxAtomicInlineWidth = 128; + } + BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::CharPtrBuiltinVaList; } diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -73,6 +73,8 @@ HasROPProtect = true; } else if (Feature == "+privileged") { HasPrivileged = true; + } else if (Feature == "+quadword-atomics") { + HasQuadwordAtomics = true; } // TODO: Finish this list and add an assert that we've handled them // all. @@ -352,6 +354,11 @@ .Case("pwr9", true) .Case("pwr8", true) .Default(false); + Features["quadword-atomics"] = + getTriple().isArch64Bit() && llvm::StringSwitch(CPU) + .Case("pwr9", true) + .Case("pwr8", true) + .Default(false); // ROP Protect is off by default. Features["rop-protect"] = false; @@ -449,6 +456,7 @@ .Case("mma", HasMMA) .Case("rop-protect", HasROPProtect) .Case("privileged", HasPrivileged) + .Case("quadword-atomics", HasQuadwordAtomics) .Default(false); } diff --git a/clang/test/CodeGen/ppc64-quadword-atomics.c b/clang/test/CodeGen/ppc64-quadword-atomics.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/ppc64-quadword-atomics.c @@ -0,0 +1,16 @@ +// RUN: %clang -target powerpc64-ibm-aix-xcoff -mcpu=pwr8 -S -emit-llvm -o - \ +// RUN: %s | FileCheck %s +// RUN: %clang -target powerpc64-ibm-aix-xcoff -mcpu=pwr9 -S -emit-llvm -o - \ +// RUN: %s | FileCheck %s +// RUN: %clang -target powerpc64-ibm-aix-xcoff -mcpu=pwr10 -S -emit-llvm -o - \ +// RUN: %s | FileCheck %s + +struct Quadword { long long a[2]; } __attribute__((aligned (16))); + +// CHECK-NOT: call void @__atomic_exchange +// CHECK: +quadword-atomics +struct Quadword test_xchg(struct Quadword *ptr, struct Quadword new) { + struct Quadword old; + __atomic_exchange(ptr, &new, &old, __ATOMIC_SEQ_CST); + return old; +}