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,122 @@ 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
- // 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
21
20
// CIR: cir.return
22
21
22
+ // LLVM-LABEL: @applyThreadFence
23
+ // LLVM: fence seq_cst
24
+ // LLVM: ret void
25
+
23
26
void applySignalFence () {
24
- __atomic_signal_fence (5 );
27
+ __atomic_signal_fence (__ATOMIC_SEQ_CST );
25
28
}
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
29
31
// CIR: cir.return
30
32
33
+ // LLVM-LABEL: @applySignalFence
34
+ // LLVM: fence syncscope("singlethread") seq_cst
35
+ // LLVM: ret void
36
+
31
37
void modifyWithThreadFence (DataPtr d ) {
32
- __atomic_thread_fence (5 );
38
+ __atomic_thread_fence (__ATOMIC_SEQ_CST );
33
39
d -> value = 42 ;
34
40
}
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>
44
48
// CIR: cir.return
45
49
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
+
46
58
void modifyWithSignalFence (DataPtr d ) {
47
- __atomic_signal_fence (5 );
59
+ __atomic_signal_fence (__ATOMIC_SEQ_CST );
48
60
d -> value = 24 ;
49
61
}
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>
59
69
// CIR: cir.return
60
70
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
+
61
79
void 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 );
64
82
}
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>
79
94
// CIR: cir.return
80
95
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
+
81
107
void 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 );
84
110
}
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>
99
122
// 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