Skip to content

Commit 1451f9d

Browse files
committed
[clang][CodeGen] Emit atomic IR in place of optimized libcalls.
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. Currently, the onus of handling atomics is split between Clang and the backend. We'd like to move as much as possible to the backend, since many decisions require target information. This also centralizes the logic, which helps avoid accidentally emitting both libcalls and native instructions for the same member.
1 parent 8928622 commit 1451f9d

File tree

13 files changed

+280
-528
lines changed

13 files changed

+280
-528
lines changed

clang/lib/CodeGen/CGAtomic.cpp

Lines changed: 40 additions & 275 deletions
Large diffs are not rendered by default.

clang/test/CodeGen/LoongArch/atomics.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ void test_i32_atomics(_Atomic(int32_t) * a, int32_t b) {
3333
}
3434

3535
void test_i64_atomics(_Atomic(int64_t) * a, int64_t b) {
36-
// LA32: call i64 @__atomic_load_8
37-
// LA32: call void @__atomic_store_8
38-
// LA32: call i64 @__atomic_fetch_add_8
36+
// LA32: load atomic i64, ptr %a seq_cst, align 8
37+
// LA32: store atomic i64 %b, ptr %a seq_cst, align 8
38+
// LA32: atomicrmw add ptr %a, i64 %b seq_cst
3939
// LA64: load atomic i64, ptr %a seq_cst, align 8
4040
// LA64: store atomic i64 %b, ptr %a seq_cst, align 8
4141
// LA64: atomicrmw add ptr %a, i64 %b seq_cst

clang/test/CodeGen/PowerPC/quadword-atomics.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ typedef __int128_t int128_t;
2323
// PPC64-QUADWORD-ATOMICS: [[TMP3:%.*]] = load atomic i128, ptr [[TMP1:%.*]] acquire, align 16
2424
//
2525
// PPC64-LABEL: @test_load(
26-
// PPC64: call void @__atomic_load(i64 noundef 16, ptr noundef [[TMP3:%.*]], ptr noundef [[TMP4:%.*]], i32 noundef signext 2)
26+
// PPC64: [[TMP3:%.*]] = load atomic i128, ptr [[TMP1:%.*]] acquire, align 16
2727
//
2828
Q test_load(AtomicQ *ptr) {
2929
// expected-no-diagnostics
@@ -34,7 +34,7 @@ Q test_load(AtomicQ *ptr) {
3434
// PPC64-QUADWORD-ATOMICS: store atomic i128 [[TMP6:%.*]], ptr [[TMP4:%.*]] release, align 16
3535
//
3636
// PPC64-LABEL: @test_store(
37-
// PPC64: call void @__atomic_store(i64 noundef 16, ptr noundef [[TMP6:%.*]], ptr noundef [[TMP7:%.*]], i32 noundef signext 3)
37+
// PPC64: store atomic i128 [[TMP6:%.*]], ptr [[TMP4:%.*]] release, align 16
3838
//
3939
void test_store(Q val, AtomicQ *ptr) {
4040
// expected-no-diagnostics
@@ -45,7 +45,7 @@ void test_store(Q val, AtomicQ *ptr) {
4545
// PPC64-QUADWORD-ATOMICS: [[TMP3:%.*]] = atomicrmw add ptr [[TMP0:%.*]], i128 [[TMP2:%.*]] monotonic, align 16
4646
//
4747
// PPC64-LABEL: @test_add(
48-
// PPC64: [[CALL:%.*]] = call i128 @__atomic_fetch_add_16(ptr noundef [[TMP2:%.*]], i128 noundef [[TMP3:%.*]], i32 noundef signext 0)
48+
// PPC64: [[ATOMICRMW:%.*]] = atomicrmw add ptr [[TMP0:%.*]], i128 [[TMP2:%.*]] monotonic, align 16
4949
//
5050
void test_add(_Atomic(int128_t) *ptr, int128_t x) {
5151
// expected-no-diagnostics
@@ -56,7 +56,7 @@ void test_add(_Atomic(int128_t) *ptr, int128_t x) {
5656
// PPC64-QUADWORD-ATOMICS: [[TMP8:%.*]] = atomicrmw xchg ptr [[TMP4:%.*]], i128 [[TMP7:%.*]] seq_cst, align 16
5757
//
5858
// PPC64-LABEL: @test_xchg(
59-
// PPC64: call void @__atomic_exchange(i64 noundef 16, ptr noundef [[TMP7:%.*]], ptr noundef [[TMP8:%.*]], ptr noundef [[TMP9:%.*]], i32 noundef signext 5)
59+
// PPC64: [[TMP8:%.*]] = atomicrmw xchg ptr [[TMP4:%.*]], i128 [[TMP7:%.*]] seq_cst, align 16
6060
//
6161
Q test_xchg(AtomicQ *ptr, Q new) {
6262
// expected-no-diagnostics
@@ -67,7 +67,7 @@ Q test_xchg(AtomicQ *ptr, Q new) {
6767
// PPC64-QUADWORD-ATOMICS: [[TMP10:%.*]] = cmpxchg ptr [[TMP5:%.*]], i128 [[TMP8:%.*]], i128 [[TMP9:%.*]] seq_cst monotonic, align 16
6868
//
6969
// PPC64-LABEL: @test_cmpxchg(
70-
// PPC64: [[CALL:%.*]] = call zeroext i1 @__atomic_compare_exchange(i64 noundef 16, ptr noundef [[TMP8:%.*]], ptr noundef [[TMP9:%.*]], ptr noundef [[TMP10:%.*]], i32 noundef signext 5, i32 noundef signext 0)
70+
// PPC64: [[TMP10:%.*]] = cmpxchg ptr [[TMP5:%.*]], i128 [[TMP8:%.*]], i128 [[TMP9:%.*]] seq_cst monotonic, align 16
7171
//
7272
int test_cmpxchg(AtomicQ *ptr, Q *cmp, Q new) {
7373
// expected-no-diagnostics
@@ -78,7 +78,7 @@ int test_cmpxchg(AtomicQ *ptr, Q *cmp, Q new) {
7878
// PPC64-QUADWORD-ATOMICS: [[TMP10:%.*]] = cmpxchg weak ptr [[TMP5:%.*]], i128 [[TMP8:%.*]], i128 [[TMP9:%.*]] seq_cst monotonic, align 16
7979
//
8080
// PPC64-LABEL: @test_cmpxchg_weak(
81-
// PPC64: [[CALL:%.*]] = call zeroext i1 @__atomic_compare_exchange(i64 noundef 16, ptr noundef [[TMP8:%.*]], ptr noundef [[TMP9:%.*]], ptr noundef [[TMP10:%.*]], i32 noundef signext 5, i32 noundef signext 0)
81+
// PPC64: [[TMP10:%.*]] = cmpxchg weak ptr [[TMP5:%.*]], i128 [[TMP8:%.*]], i128 [[TMP9:%.*]] seq_cst monotonic, align 16
8282
//
8383
int test_cmpxchg_weak(AtomicQ *ptr, Q *cmp, Q new) {
8484
// expected-no-diagnostics

clang/test/CodeGen/RISCV/riscv-atomics.c

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,19 @@
77
// RUN: %clang_cc1 -triple riscv64 -target-feature +a -O1 -emit-llvm %s -o - \
88
// RUN: | FileCheck %s -check-prefix=RV64IA
99

10-
// This test demonstrates that MaxAtomicInlineWidth is set appropriately when
11-
// the atomics instruction set extension is enabled.
12-
1310
#include <stdatomic.h>
1411
#include <stdint.h>
1512

1613
void test_i8_atomics(_Atomic(int8_t) * a, int8_t b) {
17-
// RV32I: call zeroext i8 @__atomic_load_1
18-
// RV32I: call void @__atomic_store_1
19-
// RV32I: call zeroext i8 @__atomic_fetch_add_1
14+
// RV32I: load atomic i8, ptr %a seq_cst, align 1
15+
// RV32I: store atomic i8 %b, ptr %a seq_cst, align 1
16+
// RV32I: atomicrmw add ptr %a, i8 %b seq_cst, align 1
2017
// RV32IA: load atomic i8, ptr %a seq_cst, align 1
2118
// RV32IA: store atomic i8 %b, ptr %a seq_cst, align 1
2219
// RV32IA: atomicrmw add ptr %a, i8 %b seq_cst, align 1
23-
// RV64I: call zeroext i8 @__atomic_load_1
24-
// RV64I: call void @__atomic_store_1
25-
// RV64I: call zeroext i8 @__atomic_fetch_add_1
20+
// RV64I: load atomic i8, ptr %a seq_cst, align 1
21+
// RV64I: store atomic i8 %b, ptr %a seq_cst, align 1
22+
// RV64I: atomicrmw add ptr %a, i8 %b seq_cst, align 1
2623
// RV64IA: load atomic i8, ptr %a seq_cst, align 1
2724
// RV64IA: store atomic i8 %b, ptr %a seq_cst, align 1
2825
// RV64IA: atomicrmw add ptr %a, i8 %b seq_cst, align 1
@@ -32,15 +29,15 @@ void test_i8_atomics(_Atomic(int8_t) * a, int8_t b) {
3229
}
3330

3431
void test_i32_atomics(_Atomic(int32_t) * a, int32_t b) {
35-
// RV32I: call i32 @__atomic_load_4
36-
// RV32I: call void @__atomic_store_4
37-
// RV32I: call i32 @__atomic_fetch_add_4
32+
// RV32I: load atomic i32, ptr %a seq_cst, align 4
33+
// RV32I: store atomic i32 %b, ptr %a seq_cst, align 4
34+
// RV32I: atomicrmw add ptr %a, i32 %b seq_cst, align 4
3835
// RV32IA: load atomic i32, ptr %a seq_cst, align 4
3936
// RV32IA: store atomic i32 %b, ptr %a seq_cst, align 4
4037
// RV32IA: atomicrmw add ptr %a, i32 %b seq_cst, align 4
41-
// RV64I: call signext i32 @__atomic_load_4
42-
// RV64I: call void @__atomic_store_4
43-
// RV64I: call signext i32 @__atomic_fetch_add_4
38+
// RV64I: load atomic i32, ptr %a seq_cst, align 4
39+
// RV64I: store atomic i32 %b, ptr %a seq_cst, align 4
40+
// RV64I: atomicrmw add ptr %a, i32 %b seq_cst, align 4
4441
// RV64IA: load atomic i32, ptr %a seq_cst, align 4
4542
// RV64IA: store atomic i32 %b, ptr %a seq_cst, align 4
4643
// RV64IA: atomicrmw add ptr %a, i32 %b seq_cst, align 4
@@ -50,15 +47,15 @@ void test_i32_atomics(_Atomic(int32_t) * a, int32_t b) {
5047
}
5148

5249
void test_i64_atomics(_Atomic(int64_t) * a, int64_t b) {
53-
// RV32I: call i64 @__atomic_load_8
54-
// RV32I: call void @__atomic_store_8
55-
// RV32I: call i64 @__atomic_fetch_add_8
56-
// RV32IA: call i64 @__atomic_load_8
57-
// RV32IA: call void @__atomic_store_8
58-
// RV32IA: call i64 @__atomic_fetch_add_8
59-
// RV64I: call i64 @__atomic_load_8
60-
// RV64I: call void @__atomic_store_8
61-
// RV64I: call i64 @__atomic_fetch_add_8
50+
// RV32I: load atomic i64, ptr %a seq_cst, align 8
51+
// RV32I: store atomic i64 %b, ptr %a seq_cst, align 8
52+
// RV32I: atomicrmw add ptr %a, i64 %b seq_cst, align 8
53+
// RV32IA: load atomic i64, ptr %a seq_cst, align 8
54+
// RV32IA: store atomic i64 %b, ptr %a seq_cst, align 8
55+
// RV32IA: atomicrmw add ptr %a, i64 %b seq_cst, align 8
56+
// RV64I: load atomic i64, ptr %a seq_cst, align 8
57+
// RV64I: store atomic i64 %b, ptr %a seq_cst, align 8
58+
// RV64I: atomicrmw add ptr %a, i64 %b seq_cst, align 8
6259
// RV64IA: load atomic i64, ptr %a seq_cst, align 8
6360
// RV64IA: store atomic i64 %b, ptr %a seq_cst, align 8
6461
// RV64IA: atomicrmw add ptr %a, i64 %b seq_cst, align 8

0 commit comments

Comments
 (0)