llvm-project/clang/test/CodeGen/PowerPC/quadword-atomics.c
Logikable 5fdd094837
[clang][CodeGen] Emit atomic IR in place of optimized libcalls. (#73176)
In the beginning, Clang only emitted atomic IR for operations it knew
the
underlying microarch had instructions for, meaning it required
significant
knowledge of the target. Later, the backend acquired the ability to
lower
IR to libcalls. To avoid duplicating logic and improve logic locality,
we'd like to move as much as possible to the backend.

There are many ways to describe this change. For example, this change
reduces the variables Clang uses to decide whether to emit libcalls or
IR, down to only the atomic's size.
2024-02-12 09:33:09 -08:00

85 lines
3.1 KiB
C

// RUN: %clang_cc1 -Werror -Wno-atomic-alignment -triple powerpc64le-linux-gnu \
// RUN: -target-cpu pwr8 -emit-llvm -o - %s | FileCheck %s \
// RUN: --check-prefixes=PPC64,PPC64-QUADWORD-ATOMICS
// RUN: %clang_cc1 -Werror -Wno-atomic-alignment -triple powerpc64le-linux-gnu \
// RUN: -emit-llvm -o - %s | FileCheck %s \
// RUN: --check-prefixes=PPC64,PPC64-NO-QUADWORD-ATOMICS
// RUN: %clang_cc1 -Werror -Wno-atomic-alignment -triple powerpc64-unknown-aix \
// RUN: -target-cpu pwr7 -emit-llvm -o - %s | FileCheck %s \
// RUN: --check-prefixes=PPC64,PPC64-NO-QUADWORD-ATOMICS
// RUN: %clang_cc1 -Werror -Wno-atomic-alignment -triple powerpc64-unknown-aix \
// RUN: -target-cpu pwr8 -emit-llvm -o - %s | FileCheck %s \
// RUN: --check-prefixes=PPC64,PPC64-NO-QUADWORD-ATOMICS
// RUN: %clang_cc1 -Werror -Wno-atomic-alignment -triple powerpc64-unknown-aix \
// RUN: -mabi=quadword-atomics -target-cpu pwr8 -emit-llvm -o - %s | \
// RUN: FileCheck %s --check-prefixes=PPC64,PPC64-QUADWORD-ATOMICS
typedef struct {
char x[16];
} Q;
typedef _Atomic(Q) AtomicQ;
typedef __int128_t int128_t;
// PPC64-LABEL: @test_load(
// PPC64: [[TMP3:%.*]] = load atomic i128, ptr [[TMP1:%.*]] acquire, align 16
//
Q test_load(AtomicQ *ptr) {
// expected-no-diagnostics
return __c11_atomic_load(ptr, __ATOMIC_ACQUIRE);
}
// PPC64-LABEL: @test_store(
// PPC64: store atomic i128 [[TMP6:%.*]], ptr [[TMP4:%.*]] release, align 16
//
void test_store(Q val, AtomicQ *ptr) {
// expected-no-diagnostics
__c11_atomic_store(ptr, val, __ATOMIC_RELEASE);
}
// PPC64-LABEL: @test_add(
// PPC64: [[ATOMICRMW:%.*]] = atomicrmw add ptr [[TMP0:%.*]], i128 [[TMP2:%.*]] monotonic, align 16
//
void test_add(_Atomic(int128_t) *ptr, int128_t x) {
// expected-no-diagnostics
__c11_atomic_fetch_add(ptr, x, __ATOMIC_RELAXED);
}
// PPC64-LABEL: @test_xchg(
// PPC64: [[TMP8:%.*]] = atomicrmw xchg ptr [[TMP4:%.*]], i128 [[TMP7:%.*]] seq_cst, align 16
//
Q test_xchg(AtomicQ *ptr, Q new) {
// expected-no-diagnostics
return __c11_atomic_exchange(ptr, new, __ATOMIC_SEQ_CST);
}
// PPC64-LABEL: @test_cmpxchg(
// PPC64: [[TMP10:%.*]] = cmpxchg ptr [[TMP5:%.*]], i128 [[TMP8:%.*]], i128 [[TMP9:%.*]] seq_cst monotonic, align 16
//
int test_cmpxchg(AtomicQ *ptr, Q *cmp, Q new) {
// expected-no-diagnostics
return __c11_atomic_compare_exchange_strong(ptr, cmp, new, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
}
// PPC64-LABEL: @test_cmpxchg_weak(
// PPC64: [[TMP10:%.*]] = cmpxchg weak ptr [[TMP5:%.*]], i128 [[TMP8:%.*]], i128 [[TMP9:%.*]] seq_cst monotonic, align 16
//
int test_cmpxchg_weak(AtomicQ *ptr, Q *cmp, Q new) {
// expected-no-diagnostics
return __c11_atomic_compare_exchange_weak(ptr, cmp, new, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED);
}
// PPC64-QUADWORD-ATOMICS-LABEL: @is_lock_free(
// PPC64-QUADWORD-ATOMICS: ret i32 1
//
// PPC64-NO-QUADWORD-ATOMICS-LABEL: @is_lock_free(
// PPC64-NO-QUADWORD-ATOMICS: [[CALL:%.*]] = call zeroext i1 @__atomic_is_lock_free(i64 noundef 16, ptr noundef null)
//
int is_lock_free() {
AtomicQ q;
// expected-no-diagnostics
return __c11_atomic_is_lock_free(sizeof(q));
}