1
1
// RUN: %clang_cc1 -triple aarch64-none-linux-android21 -fclangir -emit-cir %s -o %t.cir
2
2
// 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
5
5
6
6
7
7
struct Data {
@@ -12,88 +12,138 @@ struct Data {
12
12
typedef struct Data * DataPtr ;
13
13
14
14
void applyThreadFence () {
15
- __atomic_thread_fence (5 );
15
+ __atomic_thread_fence (__ATOMIC_SEQ_CST );
16
16
}
17
17
18
18
// CIR-LABEL: cir.func no_proto @applyThreadFence
19
19
// CIR: %0 = cir.const #cir.int<5> : !s32i
20
20
// CIR: cir.atomic.fence(sync_scope = system, ordering = seq_cst)
21
21
// CIR: cir.return
22
22
23
+ // LLVM-LABEL: @applyThreadFence
24
+ // LLVM: fence seq_cst
25
+ // LLVM: ret void
26
+
23
27
void applySignalFence () {
24
- __atomic_signal_fence (5 );
28
+ __atomic_signal_fence (__ATOMIC_SEQ_CST );
25
29
}
26
30
// CIR-LABEL: cir.func no_proto @applySignalFence
27
31
// CIR: %0 = cir.const #cir.int<5> : !s32i
28
- // CIR: cir.atomic.fence(sync_scope = single_thread , ordering = seq_cst)
32
+ // CIR: cir.atomic.fence(sync_scope = singlethread , ordering = seq_cst)
29
33
// CIR: cir.return
30
34
35
+ // LLVM-LABEL: @applySignalFence
36
+ // LLVM: fence syncscope("singlethread") seq_cst
37
+ // LLVM: ret void
38
+
31
39
void modifyWithThreadFence (DataPtr d ) {
32
- __atomic_thread_fence (5 );
40
+ __atomic_thread_fence (__ATOMIC_SEQ_CST );
33
41
d -> value = 42 ;
34
42
}
35
43
// 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>>
44
+ // CIR: %[[DATA:.*]] = cir.alloca !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>, ["d", init] {alignment = 8 : i64}
45
+ // CIR: cir.store %arg0, %[[DATA]] : !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>
38
46
// CIR: %1 = cir.const #cir.int<5> : !s32i
39
47
// 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>
48
+ // CIR: %[[VAL_42:.*]] = cir.const #cir.int<42> : !s32i
49
+ // CIR: %[[LOAD_DATA:.*]] = cir.load %[[DATA]] : !cir.ptr<!cir.ptr<!ty_Data>>, !cir.ptr<!ty_Data>
50
+ // CIR: %[[DATA_VALUE:.*]] = cir.get_member %[[LOAD_DATA]] [0] {name = "value"} : !cir.ptr<!ty_Data> -> !cir.ptr<!s32i>
51
+ // CIR: cir.store %[[VAL_42]] , %[[DATA_VALUE]] : !s32i, !cir.ptr<!s32i>
44
52
// CIR: cir.return
45
53
54
+ // LLVM-LABEL: @modifyWithThreadFence
55
+ // LLVM: %[[DATA:.*]] = alloca ptr, i64 1, align 8
56
+ // LLVM: store ptr %0, ptr %[[DATA]], align 8
57
+ // LLVM: fence seq_cst
58
+ // LLVM: %[[DATA_PTR:.*]] = load ptr, ptr %[[DATA]], align 8
59
+ // LLVM: %[[DATA_VALUE:.*]] = getelementptr %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 0
60
+ // LLVM: store i32 42, ptr %[[DATA_VALUE]], align 4
61
+ // LLVM: ret void
62
+
46
63
void modifyWithSignalFence (DataPtr d ) {
47
- __atomic_signal_fence (5 );
64
+ __atomic_signal_fence (__ATOMIC_SEQ_CST );
48
65
d -> value = 24 ;
49
66
}
50
67
// 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>>
68
+ // CIR: %[[DATA:.*]] = cir.alloca !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>, ["d", init] {alignment = 8 : i64}
69
+ // CIR: cir.store %arg0, %[[DATA]] : !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>
53
70
// 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>
71
+ // CIR: cir.atomic.fence(sync_scope = singlethread , ordering = seq_cst)
72
+ // CIR: %[[VAL_42:.*]] = cir.const #cir.int<24> : !s32i
73
+ // CIR: %[[LOAD_DATA:.*]] = cir.load %[[DATA]] : !cir.ptr<!cir.ptr<!ty_Data>>, !cir.ptr<!ty_Data>
74
+ // CIR: %[[DATA_VALUE:.*]] = cir.get_member %[[LOAD_DATA]] [0] {name = "value"} : !cir.ptr<!ty_Data> -> !cir.ptr<!s32i>
75
+ // CIR: cir.store %[[VAL_42]] , %[[DATA_VALUE]] : !s32i, !cir.ptr<!s32i>
59
76
// CIR: cir.return
60
77
78
+ // LLVM-LABEL: @modifyWithSignalFence
79
+ // LLVM: %[[DATA:.*]] = alloca ptr, i64 1, align 8
80
+ // LLVM: store ptr %0, ptr %[[DATA]], align 8
81
+ // LLVM: fence syncscope("singlethread") seq_cst
82
+ // LLVM: %[[DATA_PTR:.*]] = load ptr, ptr %[[DATA]], align 8
83
+ // LLVM: %[[DATA_VALUE:.*]] = getelementptr %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 0
84
+ // LLVM: store i32 24, ptr %[[DATA_VALUE]], align 4
85
+ // LLVM: ret void
86
+
61
87
void loadWithThreadFence (DataPtr d ) {
62
- __atomic_thread_fence (5 );
63
- __atomic_load_n (& d -> ptr , 5 );
88
+ __atomic_thread_fence (__ATOMIC_SEQ_CST );
89
+ __atomic_load_n (& d -> ptr , __ATOMIC_SEQ_CST );
64
90
}
65
91
// 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>>
92
+ // CIR: %[[DATA:.*]] = cir.alloca !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>, ["d", init] {alignment = 8 : i64}
93
+ // CIR: %[[ATOMIC_TEMP:.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["atomic-temp"] {alignment = 8 : i64}
94
+ // CIR: cir.store %arg0, %[[DATA]] : !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>
69
95
// CIR: %2 = cir.const #cir.int<5> : !s32i
70
96
// 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>>
97
+ // CIR: %[[LOAD_DATA:.*]] = cir.load %[[DATA]] : !cir.ptr<!cir.ptr<!ty_Data>>, !cir.ptr<!ty_Data>
98
+ // CIR: %[[DATA_VALUE:.*]] = cir.get_member %[[LOAD_DATA]] [1] {name = "ptr"} : !cir.ptr<!ty_Data> -> !cir.ptr<!cir.ptr<!void>>
73
99
// 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>
100
+ // CIR: %[[CASTED_DATA_VALUE:.*]] = cir.cast(bitcast, %[[DATA_VALUE]] : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
101
+ // CIR: %[[ATOMIC_LOAD:.*]] = cir.load atomic(seq_cst) %[[CASTED_DATA_VALUE]] : !cir.ptr<!u64i>, !u64i
102
+ // CIR: %[[CASTED_ATOMIC_TEMP:.*]] = cir.cast(bitcast, %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
103
+ // CIR: cir.store %[[ATOMIC_LOAD]] , %[[CASTED_ATOMIC_TEMP]] : !u64i, !cir.ptr<!u64i>
104
+ // CIR: %[[ATOMIC_LOAD_PTR:.*]] = cir.load %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
79
105
// CIR: cir.return
80
106
107
+ // LLVM-LABEL: @loadWithThreadFence
108
+ // LLVM: %[[DATA:.*]] = alloca ptr, i64 1, align 8
109
+ // LLVM: %[[DATA_TEMP:.*]] = alloca ptr, i64 1, align 8
110
+ // LLVM: store ptr %0, ptr %[[DATA]], align 8
111
+ // LLVM: fence seq_cst
112
+ // LLVM: %[[DATA_PTR:.*]] = load ptr, ptr %2, align 8
113
+ // LLVM: %[[DATA_VALUE:.*]] = getelementptr %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 1
114
+ // LLVM: %[[ATOMIC_LOAD:.*]] = load atomic i64, ptr %[[DATA_VALUE]] seq_cst, align 8
115
+ // LLVM: store i64 %[[ATOMIC_LOAD]], ptr %[[DATA_TEMP]], align 8
116
+ // LLVM: %[[DATA_TEMP_LOAD:.*]] = load ptr, ptr %[[DATA_TEMP]], align 8
117
+ // LLVM: ret void
118
+
81
119
void loadWithSignalFence (DataPtr d ) {
82
- __atomic_signal_fence (5 );
83
- __atomic_load_n (& d -> ptr , 5 );
120
+ __atomic_signal_fence (__ATOMIC_SEQ_CST );
121
+ __atomic_load_n (& d -> ptr , __ATOMIC_SEQ_CST );
84
122
}
85
123
// 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>>
124
+ // CIR: %[[DATA:.*]] = cir.alloca !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>, ["d", init] {alignment = 8 : i64}
125
+ // CIR: %[[ATOMIC_TEMP:.*]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>, ["atomic-temp"] {alignment = 8 : i64}
126
+ // CIR: cir.store %arg0, %[[DATA]] : !cir.ptr<!ty_Data>, !cir.ptr<!cir.ptr<!ty_Data>>
89
127
// 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>>
128
+ // CIR: cir.atomic.fence(sync_scope = singlethread , ordering = seq_cst)
129
+ // CIR: %[[LOAD_DATA:.*]] = cir.load %[[DATA]] : !cir.ptr<!cir.ptr<!ty_Data>>, !cir.ptr<!ty_Data>
130
+ // CIR: %[[DATA_PTR:.*]] = cir.get_member %[[LOAD_DATA]] [1] {name = "ptr"} : !cir.ptr<!ty_Data> -> !cir.ptr<!cir.ptr<!void>>
93
131
// 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>
132
+ // CIR: %[[CASTED_DATA_PTR:.*]] = cir.cast(bitcast, %[[DATA_PTR]] : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
133
+ // CIR: %[[ATOMIC_LOAD:.*]] = cir.load atomic(seq_cst) %[[CASTED_DATA_PTR]] : !cir.ptr<!u64i>, !u64i
134
+ // CIR: %[[CASTED_ATOMIC_TEMP:.*]] = cir.cast(bitcast, %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>), !cir.ptr<!u64i>
135
+ // CIR: cir.store %[[ATOMIC_LOAD]] , %[[CASTED_ATOMIC_TEMP]] : !u64i, !cir.ptr<!u64i>
136
+ // CIR: %[[LOAD_ATOMIC_TEMP:.*]] = cir.load %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
99
137
// CIR: cir.return
138
+
139
+ // LLVM-LABEL: @loadWithSignalFence
140
+ // LLVM: %[[DATA:.*]] = alloca ptr, i64 1, align 8
141
+ // LLVM: %[[DATA_TEMP:.*]] = alloca ptr, i64 1, align 8
142
+ // LLVM: store ptr %0, ptr %[[DATA]], align 8
143
+ // LLVM: fence syncscope("singlethread") seq_cst
144
+ // LLVM: %[[DATA_PTR:.*]] = load ptr, ptr %[[DATA]], align 8
145
+ // LLVM: %[[DATA_VALUE:.*]] = getelementptr %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 1
146
+ // LLVM: %[[ATOMIC_LOAD:.*]] = load atomic i64, ptr %[[DATA_VALUE]] seq_cst, align 8
147
+ // LLVM: store i64 %[[ATOMIC_LOAD]], ptr %[[DATA_TEMP]], align 8
148
+ // LLVM: %[[DATA_TEMP_LOAD]] = load ptr, ptr %[[DATA_TEMP]], align 8
149
+ // LLVM: ret void
0 commit comments