[PATCH] D122377: [PowerPC][Linux] Support 16-byte lock free atomics on pwr8 and up
hubert.reinterpretcast added inline comments. Comment at: clang/lib/Basic/Targets/PPC.h:448 + void setMaxAtomicWidth() override { +// For layout on ELF targets, we support up to 16 bytes. +if (getTriple().isOSBinFormatELF()) I believe this should be presented more as this override being implemented currently only for ELF targets. The current presentation seems to imply more design intent for non-ELF targets than there is consensus for. For example: ``` if (!getTriple().isOSBinFormatELF()) return PPCTargetInfo::setMaxAtomicWidth(); ``` Comment at: clang/test/Sema/atomic-ops.c:13 +// RUN: -target-cpu pwr8 -DPPC64_PWR8 // Basic parsing/Sema tests for __c11_atomic_* This will need a separate patch to cover ppc32 (likely with AIX). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D122377/new/ https://reviews.llvm.org/D122377 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D122377: [PowerPC][Linux] Support 16-byte lock free atomics on pwr8 and up
hubert.reinterpretcast added inline comments. Comment at: clang/test/CodeGen/PowerPC/atomic-alignment.c:34 // PPC32: @o = global %struct.O zeroinitializer, align 1{{$}} // PPC64: @o = global %struct.O zeroinitializer, align 8{{$}} Just noting that GCC increases the alignment even for ppc32: ``` typedef struct A8 { char x[8]; } A8; typedef struct A16 { char x[16]; } A16; extern char q8[_Alignof(_Atomic(A8))], q8[8]; // okay for GCC targeting ppc32 extern char q16[_Alignof(_Atomic(A16))], q16[16]; // okay for GCC targeting ppc32 ``` Apparently, the change for i686 in GCC occurred with version 11. https://godbolt.org/z/fTTGoqWW1 Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D122377/new/ https://reviews.llvm.org/D122377 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D122377: [PowerPC][Linux] Support 16-byte lock free atomics on pwr8 and up
hubert.reinterpretcast added inline comments. Comment at: clang/test/CodeGen/PowerPC/atomic-alignment.c:45 +// PPC64: @q = global %struct.Q zeroinitializer, align 16{{$}} +// AIX64: @q = global %struct.Q zeroinitializer, align 1{{$}} _Atomic(Q) q; // expected-no-diagnostics Although it is a change that affects layout compatibility with the short history of 16-byte atomic types compiled with LLVM-based compilers on AIX, having this 16-byte atomic type aligned also on AIX for PPC64 would be reasonable. The consequences of not doing so is that operations on some types would be lock-free only on ELF-based platforms. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D122377/new/ https://reviews.llvm.org/D122377 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D122377: [PowerPC][Linux] Support 16-byte lock free atomics on pwr8 and up
efriedma added inline comments. Comment at: llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1329 setOperationAction(ISD::INTRINSIC_VOID, MVT::i128, Custom); } You probably want an "else" here to call `setMaxAtomicSizeInBitsSupported(64)` or something like that. But you can leave that to a followup patch if you want. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D122377/new/ https://reviews.llvm.org/D122377 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D122377: [PowerPC][Linux] Support 16-byte lock free atomics on pwr8 and up
lkail updated this revision to Diff 418537. lkail added a comment. Thanks @efriedma for pointing out. Updated guard code. Also adjust backend to reflect ABI change. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D122377/new/ https://reviews.llvm.org/D122377 Files: clang/lib/Basic/Targets/PPC.cpp clang/lib/Basic/Targets/PPC.h clang/test/CodeGen/PowerPC/atomic-alignment.c clang/test/CodeGen/PowerPC/quadword-atomics.c clang/test/Sema/atomic-ops.c llvm/lib/Target/PowerPC/PPCISelLowering.cpp llvm/lib/Target/PowerPC/PPCISelLowering.h llvm/test/CodeGen/PowerPC/atomics-i128.ll Index: llvm/test/CodeGen/PowerPC/atomics-i128.ll === --- llvm/test/CodeGen/PowerPC/atomics-i128.ll +++ llvm/test/CodeGen/PowerPC/atomics-i128.ll @@ -5,6 +5,15 @@ ; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-unknown -mcpu=pwr7 \ ; RUN: -ppc-asm-full-reg-names -ppc-quadword-atomics \ ; RUN: -ppc-track-subreg-liveness < %s | FileCheck --check-prefix=PWR7 %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 \ +; RUN: -ppc-asm-full-reg-names -ppc-track-subreg-liveness < %s | FileCheck \ +; RUN: --check-prefix=LE-PWR8 %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64le-unknown-freebsd -mcpu=pwr8 \ +; RUN: -ppc-asm-full-reg-names -ppc-track-subreg-liveness < %s | FileCheck \ +; RUN: --check-prefix=LE-PWR8 %s +; RUN: llc -verify-machineinstrs -mtriple=powerpc64-unknown-aix -mcpu=pwr8 \ +; RUN: -ppc-asm-full-reg-names -ppc-track-subreg-liveness < %s | FileCheck \ +; RUN: --check-prefix=AIX64-PWR8 %s define i128 @swap(i128* %a, i128 %x) { @@ -39,6 +48,36 @@ ; PWR7-NEXT:ld r0, 16(r1) ; PWR7-NEXT:mtlr r0 ; PWR7-NEXT:blr +; +; LE-PWR8-LABEL: swap: +; LE-PWR8: # %bb.0: # %entry +; LE-PWR8-NEXT:sync +; LE-PWR8-NEXT: .LBB0_1: # %entry +; LE-PWR8-NEXT:# +; LE-PWR8-NEXT:lqarx r6, 0, r3 +; LE-PWR8-NEXT:mr r9, r4 +; LE-PWR8-NEXT:mr r8, r5 +; LE-PWR8-NEXT:stqcx. r8, 0, r3 +; LE-PWR8-NEXT:bne cr0, .LBB0_1 +; LE-PWR8-NEXT: # %bb.2: # %entry +; LE-PWR8-NEXT:lwsync +; LE-PWR8-NEXT:mr r3, r7 +; LE-PWR8-NEXT:mr r4, r6 +; LE-PWR8-NEXT:blr +; +; AIX64-PWR8-LABEL: swap: +; AIX64-PWR8: # %bb.0: # %entry +; AIX64-PWR8-NEXT:mflr r0 +; AIX64-PWR8-NEXT:std r0, 16(r1) +; AIX64-PWR8-NEXT:stdu r1, -112(r1) +; AIX64-PWR8-NEXT:sync +; AIX64-PWR8-NEXT:bl .__sync_lock_test_and_set_16[PR] +; AIX64-PWR8-NEXT:nop +; AIX64-PWR8-NEXT:lwsync +; AIX64-PWR8-NEXT:addi r1, r1, 112 +; AIX64-PWR8-NEXT:ld r0, 16(r1) +; AIX64-PWR8-NEXT:mtlr r0 +; AIX64-PWR8-NEXT:blr entry: %0 = atomicrmw xchg i128* %a, i128 %x seq_cst, align 16 ret i128 %0 @@ -76,6 +115,36 @@ ; PWR7-NEXT:ld r0, 16(r1) ; PWR7-NEXT:mtlr r0 ; PWR7-NEXT:blr +; +; LE-PWR8-LABEL: add: +; LE-PWR8: # %bb.0: # %entry +; LE-PWR8-NEXT:sync +; LE-PWR8-NEXT: .LBB1_1: # %entry +; LE-PWR8-NEXT:# +; LE-PWR8-NEXT:lqarx r6, 0, r3 +; LE-PWR8-NEXT:addc r9, r4, r7 +; LE-PWR8-NEXT:adde r8, r5, r6 +; LE-PWR8-NEXT:stqcx. r8, 0, r3 +; LE-PWR8-NEXT:bne cr0, .LBB1_1 +; LE-PWR8-NEXT: # %bb.2: # %entry +; LE-PWR8-NEXT:lwsync +; LE-PWR8-NEXT:mr r3, r7 +; LE-PWR8-NEXT:mr r4, r6 +; LE-PWR8-NEXT:blr +; +; AIX64-PWR8-LABEL: add: +; AIX64-PWR8: # %bb.0: # %entry +; AIX64-PWR8-NEXT:mflr r0 +; AIX64-PWR8-NEXT:std r0, 16(r1) +; AIX64-PWR8-NEXT:stdu r1, -112(r1) +; AIX64-PWR8-NEXT:sync +; AIX64-PWR8-NEXT:bl .__sync_fetch_and_add_16[PR] +; AIX64-PWR8-NEXT:nop +; AIX64-PWR8-NEXT:lwsync +; AIX64-PWR8-NEXT:addi r1, r1, 112 +; AIX64-PWR8-NEXT:ld r0, 16(r1) +; AIX64-PWR8-NEXT:mtlr r0 +; AIX64-PWR8-NEXT:blr entry: %0 = atomicrmw add i128* %a, i128 %x seq_cst, align 16 ret i128 %0 @@ -113,6 +182,36 @@ ; PWR7-NEXT:ld r0, 16(r1) ; PWR7-NEXT:mtlr r0 ; PWR7-NEXT:blr +; +; LE-PWR8-LABEL: sub: +; LE-PWR8: # %bb.0: # %entry +; LE-PWR8-NEXT:sync +; LE-PWR8-NEXT: .LBB2_1: # %entry +; LE-PWR8-NEXT:# +; LE-PWR8-NEXT:lqarx r6, 0, r3 +; LE-PWR8-NEXT:subc r9, r7, r4 +; LE-PWR8-NEXT:subfe r8, r5, r6 +; LE-PWR8-NEXT:stqcx. r8, 0, r3 +; LE-PWR8-NEXT:bne cr0, .LBB2_1 +; LE-PWR8-NEXT: # %bb.2: # %entry +; LE-PWR8-NEXT:lwsync +; LE-PWR8-NEXT:mr r3, r7 +; LE-PWR8-NEXT:mr r4, r6 +; LE-PWR8-NEXT:blr +; +; AIX64-PWR8-LABEL: sub: +; AIX64-PWR8: # %bb.0: # %entry +; AIX64-PWR8-NEXT:mflr r0 +; AIX64-PWR8-NEXT:std r0, 16(r1) +; AIX64-PWR8-NEXT:stdu r1, -112(r1) +; AIX64-PWR8-NEXT:sync +; AIX64-PWR8-NEXT:bl .__sync_fetch_and_sub_16[PR] +; AIX64-PWR8-NEXT:nop +; AIX64-PWR8-NEXT:lwsync +; AIX64-PWR8-NEXT:addi r1, r1, 112 +; AIX64-PWR8-NEXT:ld r0, 16(r1) +; AIX64-PWR8-NEXT:mtlr r0 +; AIX64-PWR8-NEXT:blr entry: %0 = atomicrmw sub i128*
[PATCH] D122377: [PowerPC][Linux] Support 16-byte lock free atomics on pwr8 and up
efriedma added inline comments. Comment at: clang/lib/Basic/Targets/PPC.h:451 + MaxAtomicPromoteWidth = 128; + MaxAtomicInlineWidth = 128; +} MaxAtomicPromoteWidth should not depend on whether quadword-atomics is present, only the target OS. It determines the layout of `_Atomic(__int128_t)`. (MaxAtomicInlineWidth is allowed to adjust as necessary.) Comment at: clang/lib/Driver/ToolChains/Clang.cpp:2140 +CmdArgs.push_back("-mllvm"); +CmdArgs.push_back("-ppc-quadword-atomics"); + } Please avoid using "-mllvm" options like this; among other issues, it doesn't work with LTO. If we need to indicate this, please use a function attribute in the IR. (Yes, there are other cases where we translate flags to -mllvm options, but it's not something you should copy.) Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D122377/new/ https://reviews.llvm.org/D122377 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D122377: [PowerPC][Linux] Support 16-byte lock free atomics on pwr8 and up
lkail added a comment. Removed alter of `-ppc-quadword-atomcis` in backend to decouple from frontend. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D122377/new/ https://reviews.llvm.org/D122377 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D122377: [PowerPC][Linux] Support 16-byte lock free atomics on pwr8 and up
lkail updated this revision to Diff 418142. lkail added reviewers: dim, pkubaj. lkail set the repository for this revision to rG LLVM Github Monorepo. lkail added subscribers: pkubaj, dim. lkail added a comment. @dim @pkubaj We are modifying layout of 16-byte atomic type on Linux to be consistent with GCC, I don't know if it also applies to freebsd as @MaskRay pointed out. To be more specific, on Linux, for arch level supporting 16-byte lock free atomics, 16-byte atomic type is properly aligned. #include int printf(const char *, ...); typedef struct A { char x[16]; } A; typedef struct B { char q; _Atomic(A) a; } B; int main(void) { _Atomic(A) *p = 0; printf("aligned: %d\n", __builtin_offsetof(B, a) % 16 == 0); #if __clang__ printf("lock free (size built-in): %d\n", __c11_atomic_is_lock_free(sizeof(*p))); #endif printf("lock free (type query using pointer): %d\n", atomic_is_lock_free(p)); } Current clang gives aligned: 0 lock free (size built-in): 1 lock free (type query using pointer): 1 GCC gives aligned: 1 lock free (type query using pointer): 1 This patch also modifies the query of `__atomic_always_lock_free(16, 0)` to return true for supported arch level. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D122377/new/ https://reviews.llvm.org/D122377 Files: clang/lib/Basic/Targets/PPC.cpp clang/lib/Basic/Targets/PPC.h clang/lib/Driver/ToolChains/Clang.cpp clang/test/CodeGen/PowerPC/atomic-alignment.c clang/test/CodeGen/PowerPC/quadword-atomics.c clang/test/Driver/ppc-quadword-atomics.c clang/test/Sema/atomic-ops.c Index: clang/test/Sema/atomic-ops.c === --- clang/test/Sema/atomic-ops.c +++ clang/test/Sema/atomic-ops.c @@ -9,7 +9,7 @@ // RUN: -target-cpu pwr7 // RUN: %clang_cc1 %s -verify -fgnuc-version=4.2.1 -ffreestanding \ // RUN: -fsyntax-only -triple=powerpc64le-linux-gnu -std=c11 \ -// RUN: -target-cpu pwr8 +// RUN: -target-cpu pwr8 -DPPC64_PWR8 // Basic parsing/Sema tests for __c11_atomic_* @@ -47,7 +47,11 @@ _Static_assert(__c11_atomic_is_lock_free(3), ""); // expected-error {{not an integral constant expression}} _Static_assert(__c11_atomic_is_lock_free(4), ""); _Static_assert(__c11_atomic_is_lock_free(8), ""); +#ifndef PPC64_PWR8 _Static_assert(__c11_atomic_is_lock_free(16), ""); // expected-error {{not an integral constant expression}} +#else +_Static_assert(__c11_atomic_is_lock_free(16), ""); // expected-no-error +#endif _Static_assert(__c11_atomic_is_lock_free(17), ""); // expected-error {{not an integral constant expression}} _Static_assert(__atomic_is_lock_free(1, 0), ""); @@ -55,15 +59,23 @@ _Static_assert(__atomic_is_lock_free(3, 0), ""); // expected-error {{not an integral constant expression}} _Static_assert(__atomic_is_lock_free(4, 0), ""); _Static_assert(__atomic_is_lock_free(8, 0), ""); +#ifndef PPC64_PWR8 _Static_assert(__atomic_is_lock_free(16, 0), ""); // expected-error {{not an integral constant expression}} +#else +_Static_assert(__atomic_is_lock_free(16, 0), ""); // expected-no-error +#endif _Static_assert(__atomic_is_lock_free(17, 0), ""); // expected-error {{not an integral constant expression}} _Static_assert(atomic_is_lock_free((atomic_char*)0), ""); _Static_assert(atomic_is_lock_free((atomic_short*)0), ""); _Static_assert(atomic_is_lock_free((atomic_int*)0), ""); _Static_assert(atomic_is_lock_free((atomic_long*)0), ""); +#ifndef PPC64_PWR8 // noi128-error@+1 {{__int128 is not supported on this target}} _Static_assert(atomic_is_lock_free((_Atomic(__int128)*)0), ""); // expected-error {{not an integral constant expression}} +#else +_Static_assert(atomic_is_lock_free((_Atomic(__int128)*)0), ""); // expected-no-error +#endif _Static_assert(atomic_is_lock_free(0 + (atomic_char*)0), ""); char i8; @@ -88,7 +100,11 @@ _Static_assert(!__atomic_always_lock_free(3, 0), ""); _Static_assert(__atomic_always_lock_free(4, 0), ""); _Static_assert(__atomic_always_lock_free(8, 0), ""); +#ifndef PPC64_PWR8 _Static_assert(!__atomic_always_lock_free(16, 0), ""); +#else +_Static_assert(__atomic_always_lock_free(16, 0), ""); +#endif _Static_assert(!__atomic_always_lock_free(17, 0), ""); _Static_assert(__atomic_always_lock_free(1, incomplete), ""); Index: clang/test/Driver/ppc-quadword-atomics.c === --- /dev/null +++ clang/test/Driver/ppc-quadword-atomics.c @@ -0,0 +1,17 @@ +// RUN: %clang -### -target powerpc-unknown-unknown -S %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=NO-QUADWORD-ATOMICS +// RUN: %clang -### -target powerpc64-unknown-aix -S %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=NO-QUADWORD-ATOMICS +// RUN: %clang -### -target powerpc64-unknown-unknown -S %s 2>&1 | \ +// RUN: FileCheck %s +// RUN: %clang -### -target powerpc64le-unknown-unknown -S %s
[PATCH] D122377: [PowerPC][Linux] Support 16-byte lock free atomics on pwr8 and up
MaskRay added inline comments. Comment at: clang/lib/Basic/Targets/PPC.h:449 +// For layout on Linux, we support up to 16 bytes. +if (getTriple().isOSLinux() && hasFeature("quadword-atomics")) { + MaxAtomicPromoteWidth = 128; Many `isOSLinux()` usage may be really `isOSBinFormatELF()` (to help FreeBSD, etc). Can you check whether that's the case? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D122377/new/ https://reviews.llvm.org/D122377 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D122377: [PowerPC][Linux] Support 16-byte lock free atomics on pwr8 and up
jsji added inline comments. Comment at: clang/test/CodeGen/PowerPC/atomic-alignment.c:7 +// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefixes=PPC,PPC64-PWR8 // RUN: %clang_cc1 -verify -triple powerpc64-unknown-aix -emit-llvm -o - %s | \ // RUN: FileCheck %s --check-prefixes=PPC,PPC64 How about AIX pwr8? Comment at: llvm/lib/Target/PowerPC/PPCISelLowering.cpp:126 "ppc-quadword-atomics", -cl::desc("enable quadword lock-free atomic operations"), cl::init(false), +cl::desc("enable quadword lock-free atomic operations"), cl::init(true), cl::Hidden); So we enable it by default , *EVEN* on AIX? CHANGES SINCE LAST ACTION https://reviews.llvm.org/D122377/new/ https://reviews.llvm.org/D122377 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D122377: [PowerPC][Linux] Support 16-byte lock free atomics on pwr8 and up
lkail updated this revision to Diff 417868. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D122377/new/ https://reviews.llvm.org/D122377 Files: clang/lib/Basic/Targets/PPC.cpp clang/lib/Basic/Targets/PPC.h clang/test/CodeGen/PowerPC/atomic-alignment.c clang/test/CodeGen/PowerPC/quadword-atomics.c clang/test/Sema/atomic-ops.c llvm/lib/Target/PowerPC/PPCISelLowering.cpp Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp === --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -123,7 +123,7 @@ static cl::opt EnableQuadwordAtomics( "ppc-quadword-atomics", -cl::desc("enable quadword lock-free atomic operations"), cl::init(false), +cl::desc("enable quadword lock-free atomic operations"), cl::init(true), cl::Hidden); static cl::opt Index: clang/test/Sema/atomic-ops.c === --- clang/test/Sema/atomic-ops.c +++ clang/test/Sema/atomic-ops.c @@ -9,7 +9,7 @@ // RUN: -target-cpu pwr7 // RUN: %clang_cc1 %s -verify -fgnuc-version=4.2.1 -ffreestanding \ // RUN: -fsyntax-only -triple=powerpc64le-linux-gnu -std=c11 \ -// RUN: -target-cpu pwr8 +// RUN: -target-cpu pwr8 -DPPC64_PWR8 // Basic parsing/Sema tests for __c11_atomic_* @@ -47,7 +47,11 @@ _Static_assert(__c11_atomic_is_lock_free(3), ""); // expected-error {{not an integral constant expression}} _Static_assert(__c11_atomic_is_lock_free(4), ""); _Static_assert(__c11_atomic_is_lock_free(8), ""); +#ifndef PPC64_PWR8 _Static_assert(__c11_atomic_is_lock_free(16), ""); // expected-error {{not an integral constant expression}} +#else +_Static_assert(__c11_atomic_is_lock_free(16), ""); // expected-no-error +#endif _Static_assert(__c11_atomic_is_lock_free(17), ""); // expected-error {{not an integral constant expression}} _Static_assert(__atomic_is_lock_free(1, 0), ""); @@ -55,15 +59,23 @@ _Static_assert(__atomic_is_lock_free(3, 0), ""); // expected-error {{not an integral constant expression}} _Static_assert(__atomic_is_lock_free(4, 0), ""); _Static_assert(__atomic_is_lock_free(8, 0), ""); +#ifndef PPC64_PWR8 _Static_assert(__atomic_is_lock_free(16, 0), ""); // expected-error {{not an integral constant expression}} +#else +_Static_assert(__atomic_is_lock_free(16, 0), ""); // expected-no-error +#endif _Static_assert(__atomic_is_lock_free(17, 0), ""); // expected-error {{not an integral constant expression}} _Static_assert(atomic_is_lock_free((atomic_char*)0), ""); _Static_assert(atomic_is_lock_free((atomic_short*)0), ""); _Static_assert(atomic_is_lock_free((atomic_int*)0), ""); _Static_assert(atomic_is_lock_free((atomic_long*)0), ""); +#ifndef PPC64_PWR8 // noi128-error@+1 {{__int128 is not supported on this target}} _Static_assert(atomic_is_lock_free((_Atomic(__int128)*)0), ""); // expected-error {{not an integral constant expression}} +#else +_Static_assert(atomic_is_lock_free((_Atomic(__int128)*)0), ""); // expected-no-error +#endif _Static_assert(atomic_is_lock_free(0 + (atomic_char*)0), ""); char i8; @@ -88,7 +100,11 @@ _Static_assert(!__atomic_always_lock_free(3, 0), ""); _Static_assert(__atomic_always_lock_free(4, 0), ""); _Static_assert(__atomic_always_lock_free(8, 0), ""); +#ifndef PPC64_PWR8 _Static_assert(!__atomic_always_lock_free(16, 0), ""); +#else +_Static_assert(__atomic_always_lock_free(16, 0), ""); +#endif _Static_assert(!__atomic_always_lock_free(17, 0), ""); _Static_assert(__atomic_always_lock_free(1, incomplete), ""); Index: clang/test/CodeGen/PowerPC/quadword-atomics.c === --- /dev/null +++ clang/test/CodeGen/PowerPC/quadword-atomics.c @@ -0,0 +1,90 @@ +// RUN: %clang_cc1 -verify -Wno-atomic-alignment -triple powerpc64le-linux-gnu \ +// RUN: -target-cpu pwr8 -emit-llvm -o - %s | FileCheck %s --check-prefix=PPC64-PWR8 +// RUN: %clang_cc1 -verify -Wno-atomic-alignment -triple powerpc64le-linux-gnu \ +// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix=PPC64 + +typedef struct { + char x[16]; +} Q; + +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-LABEL: @test_load( +// PPC64:call void @__atomic_load(i64 noundef 16, i8* noundef [[TMP3:%.*]], i8* noundef [[TMP4:%.*]], i32 noundef signext 2) +// +Q test_load(AtomicQ *ptr) { + // expected-no-diagnostics + return __c11_atomic_load(ptr, __ATOMIC_ACQUIRE); +} + +// PPC64-PWR8-LABEL: @test_store( +// PPC64-PWR8: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) +// +void test_store(Q val, AtomicQ *ptr) { + // expected-no-diagnostics +
[PATCH] D122377: [PowerPC][Linux] Support 16-byte lock free atomics on pwr8 and up
lkail created this revision. lkail added reviewers: hubert.reinterpretcast, jsji, xingxue, PowerPC. Herald added subscribers: shchenz, kbarton, hiraditya, nemanjai. Herald added a project: All. lkail requested review of this revision. Herald added projects: clang, LLVM. Herald added subscribers: llvm-commits, cfe-commits. Enable clang of Linux on POWER supports 16-byte lock free atomics on power8 and up, so that clang can be consistent with GCC of Linux on POWER. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D122377 Files: clang/lib/Basic/Targets/PPC.cpp clang/lib/Basic/Targets/PPC.h clang/test/CodeGen/PowerPC/atomic-alignment.c clang/test/CodeGen/PowerPC/quadword-atomics.c clang/test/Sema/atomic-ops.c llvm/lib/Target/PowerPC/PPCISelLowering.cpp Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp === --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -123,7 +123,7 @@ static cl::opt EnableQuadwordAtomics( "ppc-quadword-atomics", -cl::desc("enable quadword lock-free atomic operations"), cl::init(false), +cl::desc("enable quadword lock-free atomic operations"), cl::init(true), cl::Hidden); static cl::opt Index: clang/test/Sema/atomic-ops.c === --- clang/test/Sema/atomic-ops.c +++ clang/test/Sema/atomic-ops.c @@ -9,7 +9,7 @@ // RUN: -target-cpu pwr7 // RUN: %clang_cc1 %s -verify -fgnuc-version=4.2.1 -ffreestanding \ // RUN: -fsyntax-only -triple=powerpc64le-linux-gnu -std=c11 \ -// RUN: -target-cpu pwr8 +// RUN: -target-cpu pwr8 -DPPC64_PWR8 // Basic parsing/Sema tests for __c11_atomic_* @@ -47,7 +47,11 @@ _Static_assert(__c11_atomic_is_lock_free(3), ""); // expected-error {{not an integral constant expression}} _Static_assert(__c11_atomic_is_lock_free(4), ""); _Static_assert(__c11_atomic_is_lock_free(8), ""); +#ifndef PPC64_PWR8 _Static_assert(__c11_atomic_is_lock_free(16), ""); // expected-error {{not an integral constant expression}} +#else +_Static_assert(__c11_atomic_is_lock_free(16), ""); // expected-no-error +#endif _Static_assert(__c11_atomic_is_lock_free(17), ""); // expected-error {{not an integral constant expression}} _Static_assert(__atomic_is_lock_free(1, 0), ""); @@ -55,15 +59,23 @@ _Static_assert(__atomic_is_lock_free(3, 0), ""); // expected-error {{not an integral constant expression}} _Static_assert(__atomic_is_lock_free(4, 0), ""); _Static_assert(__atomic_is_lock_free(8, 0), ""); +#ifndef PPC64_PWR8 _Static_assert(__atomic_is_lock_free(16, 0), ""); // expected-error {{not an integral constant expression}} +#else +_Static_assert(__atomic_is_lock_free(16, 0), ""); // expected-no-error +#endif _Static_assert(__atomic_is_lock_free(17, 0), ""); // expected-error {{not an integral constant expression}} _Static_assert(atomic_is_lock_free((atomic_char*)0), ""); _Static_assert(atomic_is_lock_free((atomic_short*)0), ""); _Static_assert(atomic_is_lock_free((atomic_int*)0), ""); _Static_assert(atomic_is_lock_free((atomic_long*)0), ""); +#ifndef PPC64_PWR8 // noi128-error@+1 {{__int128 is not supported on this target}} _Static_assert(atomic_is_lock_free((_Atomic(__int128)*)0), ""); // expected-error {{not an integral constant expression}} +#else +_Static_assert(atomic_is_lock_free((_Atomic(__int128)*)0), ""); // expected-no-error +#endif _Static_assert(atomic_is_lock_free(0 + (atomic_char*)0), ""); char i8; @@ -88,7 +100,11 @@ _Static_assert(!__atomic_always_lock_free(3, 0), ""); _Static_assert(__atomic_always_lock_free(4, 0), ""); _Static_assert(__atomic_always_lock_free(8, 0), ""); +#ifndef PPC64_PWR8 _Static_assert(!__atomic_always_lock_free(16, 0), ""); +#else +_Static_assert(__atomic_always_lock_free(16, 0), ""); +#endif _Static_assert(!__atomic_always_lock_free(17, 0), ""); _Static_assert(__atomic_always_lock_free(1, incomplete), ""); Index: clang/test/CodeGen/PowerPC/quadword-atomics.c === --- /dev/null +++ clang/test/CodeGen/PowerPC/quadword-atomics.c @@ -0,0 +1,91 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// RUN: %clang_cc1 -verify -Wno-atomic-alignment -triple powerpc64le-linux-gnu \ +// RUN: -target-cpu pwr8 -emit-llvm -o - %s | FileCheck %s --check-prefix=PPC64-PWR8 +// RUN: %clang_cc1 -verify -Wno-atomic-alignment -triple powerpc64le-linux-gnu \ +// RUN: -emit-llvm -o - %s | FileCheck %s --check-prefix=PPC64 + +typedef struct { + char x[16]; +} Q; + +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-LABEL: @test_load( +// PPC64:call void @__atomic_load(i64 noundef 16, i8* noundef [[TMP3:%.*]], i8* noundef [[TMP4:%.*]], i32 noundef signext 2) +// +Q