11// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -fclangir -emit-cir %s -o %t.cir
22// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
3- // UN : %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
4- // UN : FileCheck --check-prefix=LLVM --input-file=%t.ll %s
3+ // RUN : %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
4+ // RUN : FileCheck --check-prefix=LLVM --input-file=%t.ll %s
55
66
77struct Data {
@@ -12,88 +12,122 @@ struct Data {
1212typedef struct Data * DataPtr ;
1313
1414void applyThreadFence () {
15- __atomic_thread_fence (5 );
15+ __atomic_thread_fence (__ATOMIC_SEQ_CST );
1616}
1717
18- // CIR-LABEL: cir.func no_proto @applyThreadFence
19- // CIR: %0 = cir.const #cir.int<5> : !s32i
20- // CIR: cir.atomic.fence(sync_scope = system, ordering = seq_cst)
18+ // CIR-LABEL: @applyThreadFence
19+ // CIR: cir.atomic.fence system seq_cst
2120// CIR: cir.return
2221
22+ // LLVM-LABEL: @applyThreadFence
23+ // LLVM: fence seq_cst
24+ // LLVM: ret void
25+
2326void applySignalFence () {
24- __atomic_signal_fence (5 );
27+ __atomic_signal_fence (__ATOMIC_SEQ_CST );
2528}
26- // CIR-LABEL: cir.func no_proto @applySignalFence
27- // CIR: %0 = cir.const #cir.int<5> : !s32i
28- // CIR: cir.atomic.fence(sync_scope = single_thread, ordering = seq_cst)
29+ // CIR-LABEL: @applySignalFence
30+ // CIR: cir.atomic.fence single_thread seq_cst
2931// CIR: cir.return
3032
33+ // LLVM-LABEL: @applySignalFence
34+ // LLVM: fence syncscope("singlethread") seq_cst
35+ // LLVM: ret void
36+
3137void modifyWithThreadFence (DataPtr d ) {
32- __atomic_thread_fence (5 );
38+ __atomic_thread_fence (__ATOMIC_SEQ_CST );
3339 d -> value = 42 ;
3440}
35- // CIR-LABEL: cir.func @modifyWithThreadFence
36- // CIR: %0 = cir.alloca !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>, ["d", init] {alignment = 8 : i64}
37- // CIR: cir.store %arg0, %0 : !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>
38- // CIR: %1 = cir.const #cir.int<5> : !s32i
39- // CIR: cir.atomic.fence(sync_scope = system, ordering = seq_cst)
40- // CIR: %2 = cir.const #cir.int<42> : !s32i
41- // CIR: %3 = cir.load %0 : !cir.ptr<!cir.ptr<!ty_Data>>, !cir.ptr<!ty_Data>
42- // CIR: %4 = cir.get_member %3[0] {name = "value"} : !cir.ptr<!ty_Data> -> !cir.ptr<!s32i>
43- // CIR: cir.store %2, %4 : !s32i, !cir.ptr<!s32i>
41+ // CIR-LABEL: @modifyWithThreadFence
42+ // CIR: %[[DATA:.*]] = cir.alloca !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>, ["d", init] {alignment = 8 : i64}
43+ // CIR: cir.atomic.fence system seq_cst
44+ // CIR: %[[VAL_42:.*]] = cir.const #cir.int<42> : !s32i
45+ // CIR: %[[LOAD_DATA:.*]] = cir.load %[[DATA]] : !cir.ptr<!cir.ptr<!ty_Data>>, !cir.ptr<!ty_Data>
46+ // CIR: %[[DATA_VALUE:.*]] = cir.get_member %[[LOAD_DATA]][0] {name = "value"} : !cir.ptr<!ty_Data> -> !cir.ptr<!s32i>
47+ // CIR: cir.store %[[VAL_42]], %[[DATA_VALUE]] : !s32i, !cir.ptr<!s32i>
4448// CIR: cir.return
4549
50+ // LLVM-LABEL: @modifyWithThreadFence
51+ // LLVM: %[[DATA:.*]] = alloca ptr, i64 1, align 8
52+ // LLVM: fence seq_cst
53+ // LLVM: %[[DATA_PTR:.*]] = load ptr, ptr %[[DATA]], align 8
54+ // LLVM: %[[DATA_VALUE:.*]] = getelementptr %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 0
55+ // LLVM: store i32 42, ptr %[[DATA_VALUE]], align 4
56+ // LLVM: ret void
57+
4658void modifyWithSignalFence (DataPtr d ) {
47- __atomic_signal_fence (5 );
59+ __atomic_signal_fence (__ATOMIC_SEQ_CST );
4860 d -> value = 24 ;
4961}
50- // CIR-LABEL: cir.func @modifyWithSignalFence
51- // CIR: %0 = cir.alloca !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>, ["d", init] {alignment = 8 : i64}
52- // CIR: cir.store %arg0, %0 : !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>
53- // CIR: %1 = cir.const #cir.int<5> : !s32i
54- // CIR: cir.atomic.fence(sync_scope = single_thread, ordering = seq_cst)
55- // CIR: %2 = cir.const #cir.int<24> : !s32i
56- // CIR: %3 = cir.load %0 : !cir.ptr<!cir.ptr<!ty_Data>>, !cir.ptr<!ty_Data>
57- // CIR: %4 = cir.get_member %3[0] {name = "value"} : !cir.ptr<!ty_Data> -> !cir.ptr<!s32i>
58- // CIR: cir.store %2, %4 : !s32i, !cir.ptr<!s32i>
62+ // CIR-LABEL: @modifyWithSignalFence
63+ // CIR: %[[DATA:.*]] = cir.alloca !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>, ["d", init] {alignment = 8 : i64}
64+ // CIR: cir.atomic.fence single_thread seq_cst
65+ // CIR: %[[VAL_42:.*]] = cir.const #cir.int<24> : !s32i
66+ // CIR: %[[LOAD_DATA:.*]] = cir.load %[[DATA]] : !cir.ptr<!cir.ptr<!ty_Data>>, !cir.ptr<!ty_Data>
67+ // CIR: %[[DATA_VALUE:.*]] = cir.get_member %[[LOAD_DATA]][0] {name = "value"} : !cir.ptr<!ty_Data> -> !cir.ptr<!s32i>
68+ // CIR: cir.store %[[VAL_42]], %[[DATA_VALUE]] : !s32i, !cir.ptr<!s32i>
5969// CIR: cir.return
6070
71+ // LLVM-LABEL: @modifyWithSignalFence
72+ // LLVM: %[[DATA:.*]] = alloca ptr, i64 1, align 8
73+ // LLVM: fence syncscope("singlethread") seq_cst
74+ // LLVM: %[[DATA_PTR:.*]] = load ptr, ptr %[[DATA]], align 8
75+ // LLVM: %[[DATA_VALUE:.*]] = getelementptr %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 0
76+ // LLVM: store i32 24, ptr %[[DATA_VALUE]], align 4
77+ // LLVM: ret void
78+
6179void loadWithThreadFence (DataPtr d ) {
62- __atomic_thread_fence (5 );
63- __atomic_load_n (& d -> ptr , 5 );
80+ __atomic_thread_fence (__ATOMIC_SEQ_CST );
81+ __atomic_load_n (& d -> ptr , __ATOMIC_SEQ_CST );
6482}
65- // CIR-LABEL: cir.func @loadWithThreadFence
66- // CIR: %0 = cir.alloca !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>, ["d", init] {alignment = 8 : i64}
67- // CIR: %1 = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["atomic-temp"] {alignment = 8 : i64}
68- // CIR: cir.store %arg0, %0 : !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>
69- // CIR: %2 = cir.const #cir.int<5> : !s32i
70- // CIR: cir.atomic.fence(sync_scope = system, ordering = seq_cst)
71- // CIR: %3 = cir.load %0 : !cir.ptr<!cir.ptr<!ty_Data>>, !cir.ptr<!ty_Data>
72- // CIR: %4 = cir.get_member %3[1] {name = "ptr"} : !cir.ptr<!ty_Data> -> !cir.ptr<!cir.ptr<!void>>
73- // CIR: %5 = cir.const #cir.int<5> : !s32i
74- // CIR: %6 = cir.cast(bitcast, %4 : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
75- // CIR: %7 = cir.load atomic(seq_cst) %6 : !cir.ptr<!u64i>, !u64i
76- // CIR: %8 = cir.cast(bitcast, %1 : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
77- // CIR: cir.store %7, %8 : !u64i, !cir.ptr<!u64i>
78- // CIR: %9 = cir.load %1 : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
83+ // CIR-LABEL: @loadWithThreadFence
84+ // CIR: %[[DATA:.*]] = cir.alloca !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>, ["d", init] {alignment = 8 : i64}
85+ // CIR: %[[ATOMIC_TEMP:.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["atomic-temp"] {alignment = 8 : i64}
86+ // CIR: cir.atomic.fence system seq_cst
87+ // CIR: %[[LOAD_DATA:.*]] = cir.load %[[DATA]] : !cir.ptr<!cir.ptr<!ty_Data>>, !cir.ptr<!ty_Data>
88+ // CIR: %[[DATA_VALUE:.*]] = cir.get_member %[[LOAD_DATA]][1] {name = "ptr"} : !cir.ptr<!ty_Data> -> !cir.ptr<!cir.ptr<!void>>
89+ // CIR: %[[CASTED_DATA_VALUE:.*]] = cir.cast(bitcast, %[[DATA_VALUE]] : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
90+ // CIR: %[[ATOMIC_LOAD:.*]] = cir.load atomic(seq_cst) %[[CASTED_DATA_VALUE]] : !cir.ptr<!u64i>, !u64i
91+ // CIR: %[[CASTED_ATOMIC_TEMP:.*]] = cir.cast(bitcast, %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
92+ // CIR: cir.store %[[ATOMIC_LOAD]], %[[CASTED_ATOMIC_TEMP]] : !u64i, !cir.ptr<!u64i>
93+ // CIR: %[[ATOMIC_LOAD_PTR:.*]] = cir.load %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
7994// CIR: cir.return
8095
96+ // LLVM-LABEL: @loadWithThreadFence
97+ // LLVM: %[[DATA:.*]] = alloca ptr, i64 1, align 8
98+ // LLVM: %[[DATA_TEMP:.*]] = alloca ptr, i64 1, align 8
99+ // LLVM: fence seq_cst
100+ // LLVM: %[[DATA_PTR:.*]] = load ptr, ptr %[[DATA]], align 8
101+ // LLVM: %[[DATA_VALUE:.*]] = getelementptr %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 1
102+ // LLVM: %[[ATOMIC_LOAD:.*]] = load atomic i64, ptr %[[DATA_VALUE]] seq_cst, align 8
103+ // LLVM: store i64 %[[ATOMIC_LOAD]], ptr %[[DATA_TEMP]], align 8
104+ // LLVM: %[[DATA_TEMP_LOAD:.*]] = load ptr, ptr %[[DATA_TEMP]], align 8
105+ // LLVM: ret void
106+
81107void loadWithSignalFence (DataPtr d ) {
82- __atomic_signal_fence (5 );
83- __atomic_load_n (& d -> ptr , 5 );
108+ __atomic_signal_fence (__ATOMIC_SEQ_CST );
109+ __atomic_load_n (& d -> ptr , __ATOMIC_SEQ_CST );
84110}
85- // CIR-LABEL: cir.func @loadWithSignalFence
86- // CIR: %0 = cir.alloca !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>, ["d", init] {alignment = 8 : i64}
87- // CIR: %1 = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["atomic-temp"] {alignment = 8 : i64}
88- // CIR: cir.store %arg0, %0 : !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>
89- // CIR: %2 = cir.const #cir.int<5> : !s32i
90- // CIR: cir.atomic.fence(sync_scope = single_thread, ordering = seq_cst)
91- // CIR: %3 = cir.load %0 : !cir.ptr<!cir.ptr<!ty_Data>>, !cir.ptr<!ty_Data>
92- // CIR: %4 = cir.get_member %3[1] {name = "ptr"} : !cir.ptr<!ty_Data> -> !cir.ptr<!cir.ptr<!void>>
93- // CIR: %5 = cir.const #cir.int<5> : !s32i
94- // CIR: %6 = cir.cast(bitcast, %4 : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
95- // CIR: %7 = cir.load atomic(seq_cst) %6 : !cir.ptr<!u64i>, !u64i
96- // CIR: %8 = cir.cast(bitcast, %1 : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
97- // CIR: cir.store %7, %8 : !u64i, !cir.ptr<!u64i>
98- // CIR: %9 = cir.load %1 : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
111+ // CIR-LABEL: @loadWithSignalFence
112+ // CIR: %[[DATA:.*]] = cir.alloca !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>, ["d", init] {alignment = 8 : i64}
113+ // CIR: %[[ATOMIC_TEMP:.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["atomic-temp"] {alignment = 8 : i64}
114+ // CIR: cir.atomic.fence single_thread seq_cst
115+ // CIR: %[[LOAD_DATA:.*]] = cir.load %[[DATA]] : !cir.ptr<!cir.ptr<!ty_Data>>, !cir.ptr<!ty_Data>
116+ // CIR: %[[DATA_PTR:.*]] = cir.get_member %[[LOAD_DATA]][1] {name = "ptr"} : !cir.ptr<!ty_Data> -> !cir.ptr<!cir.ptr<!void>>
117+ // CIR: %[[CASTED_DATA_PTR:.*]] = cir.cast(bitcast, %[[DATA_PTR]] : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
118+ // CIR: %[[ATOMIC_LOAD:.*]] = cir.load atomic(seq_cst) %[[CASTED_DATA_PTR]] : !cir.ptr<!u64i>, !u64i
119+ // CIR: %[[CASTED_ATOMIC_TEMP:.*]] = cir.cast(bitcast, %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
120+ // CIR: cir.store %[[ATOMIC_LOAD]], %[[CASTED_ATOMIC_TEMP]] : !u64i, !cir.ptr<!u64i>
121+ // CIR: %[[LOAD_ATOMIC_TEMP:.*]] = cir.load %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
99122// CIR: cir.return
123+
124+ // LLVM-LABEL: @loadWithSignalFence
125+ // LLVM: %[[DATA:.*]] = alloca ptr, i64 1, align 8
126+ // LLVM: %[[DATA_TEMP:.*]] = alloca ptr, i64 1, align 8
127+ // LLVM: fence syncscope("singlethread") seq_cst
128+ // LLVM: %[[DATA_PTR:.*]] = load ptr, ptr %[[DATA]], align 8
129+ // LLVM: %[[DATA_VALUE:.*]] = getelementptr %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 1
130+ // LLVM: %[[ATOMIC_LOAD:.*]] = load atomic i64, ptr %[[DATA_VALUE]] seq_cst, align 8
131+ // LLVM: store i64 %[[ATOMIC_LOAD]], ptr %[[DATA_TEMP]], align 8
132+ // LLVM: %[[DATA_TEMP_LOAD]] = load ptr, ptr %[[DATA_TEMP]], align 8
133+ // LLVM: ret void
0 commit comments