1 // Test frontend handling of __sync builtins.
2 // Modified from a gcc testcase.
3 // RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - | FileCheck %s
12 unsigned long long ull
;
14 unsigned __int128 u128
;
16 void test_op_ignore (void) // CHECK-LABEL: define{{.*}} void @test_op_ignore
18 (void) __sync_fetch_and_add (&sc
, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 1
19 (void) __sync_fetch_and_add (&uc
, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 1
20 (void) __sync_fetch_and_add (&ss
, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 2
21 (void) __sync_fetch_and_add (&us
, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 2
22 (void) __sync_fetch_and_add (&si
, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 4
23 (void) __sync_fetch_and_add (&ui
, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 4
24 (void) __sync_fetch_and_add (&sll
, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 8
25 (void) __sync_fetch_and_add (&ull
, 1); // CHECK: atomicrmw add ptr {{.*}} seq_cst, align 8
27 (void) __sync_fetch_and_sub (&sc
, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 1
28 (void) __sync_fetch_and_sub (&uc
, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 1
29 (void) __sync_fetch_and_sub (&ss
, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 2
30 (void) __sync_fetch_and_sub (&us
, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 2
31 (void) __sync_fetch_and_sub (&si
, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 4
32 (void) __sync_fetch_and_sub (&ui
, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 4
33 (void) __sync_fetch_and_sub (&sll
, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 8
34 (void) __sync_fetch_and_sub (&ull
, 1); // CHECK: atomicrmw sub ptr {{.*}} seq_cst, align 8
36 (void) __sync_fetch_and_or (&sc
, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 1
37 (void) __sync_fetch_and_or (&uc
, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 1
38 (void) __sync_fetch_and_or (&ss
, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 2
39 (void) __sync_fetch_and_or (&us
, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 2
40 (void) __sync_fetch_and_or (&si
, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 4
41 (void) __sync_fetch_and_or (&ui
, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 4
42 (void) __sync_fetch_and_or (&sll
, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 8
43 (void) __sync_fetch_and_or (&ull
, 1); // CHECK: atomicrmw or ptr {{.*}} seq_cst, align 8
45 (void) __sync_fetch_and_xor (&sc
, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 1
46 (void) __sync_fetch_and_xor (&uc
, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 1
47 (void) __sync_fetch_and_xor (&ss
, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 2
48 (void) __sync_fetch_and_xor (&us
, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 2
49 (void) __sync_fetch_and_xor (&si
, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 4
50 (void) __sync_fetch_and_xor (&ui
, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 4
51 (void) __sync_fetch_and_xor (&sll
, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 8
52 (void) __sync_fetch_and_xor (&ull
, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 8
53 (void) __sync_fetch_and_xor (&u128
, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 16
54 (void) __sync_fetch_and_xor (&s128
, 1); // CHECK: atomicrmw xor ptr {{.*}} seq_cst, align 16
56 (void) __sync_fetch_and_nand (&sc
, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 1
57 (void) __sync_fetch_and_nand (&uc
, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 1
58 (void) __sync_fetch_and_nand (&ss
, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 2
59 (void) __sync_fetch_and_nand (&us
, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 2
60 (void) __sync_fetch_and_nand (&si
, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 4
61 (void) __sync_fetch_and_nand (&ui
, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 4
62 (void) __sync_fetch_and_nand (&sll
, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 8
63 (void) __sync_fetch_and_nand (&ull
, 1); // CHECK: atomicrmw nand ptr {{.*}} seq_cst, align 8
65 (void) __sync_fetch_and_and (&sc
, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 1
66 (void) __sync_fetch_and_and (&uc
, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 1
67 (void) __sync_fetch_and_and (&ss
, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 2
68 (void) __sync_fetch_and_and (&us
, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 2
69 (void) __sync_fetch_and_and (&si
, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 4
70 (void) __sync_fetch_and_and (&ui
, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 4
71 (void) __sync_fetch_and_and (&sll
, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 8
72 (void) __sync_fetch_and_and (&ull
, 1); // CHECK: atomicrmw and ptr {{.*}} seq_cst, align 8
76 void test_fetch_and_op (void) // CHECK-LABEL: define{{.*}} void @test_fetch_and_op
78 sc
= __sync_fetch_and_add (&sc
, 11); // CHECK: atomicrmw add
79 uc
= __sync_fetch_and_add (&uc
, 11); // CHECK: atomicrmw add
80 ss
= __sync_fetch_and_add (&ss
, 11); // CHECK: atomicrmw add
81 us
= __sync_fetch_and_add (&us
, 11); // CHECK: atomicrmw add
82 si
= __sync_fetch_and_add (&si
, 11); // CHECK: atomicrmw add
83 ui
= __sync_fetch_and_add (&ui
, 11); // CHECK: atomicrmw add
84 sll
= __sync_fetch_and_add (&sll
, 11); // CHECK: atomicrmw add
85 ull
= __sync_fetch_and_add (&ull
, 11); // CHECK: atomicrmw add
87 sc
= __sync_fetch_and_sub (&sc
, 11); // CHECK: atomicrmw sub
88 uc
= __sync_fetch_and_sub (&uc
, 11); // CHECK: atomicrmw sub
89 ss
= __sync_fetch_and_sub (&ss
, 11); // CHECK: atomicrmw sub
90 us
= __sync_fetch_and_sub (&us
, 11); // CHECK: atomicrmw sub
91 si
= __sync_fetch_and_sub (&si
, 11); // CHECK: atomicrmw sub
92 ui
= __sync_fetch_and_sub (&ui
, 11); // CHECK: atomicrmw sub
93 sll
= __sync_fetch_and_sub (&sll
, 11); // CHECK: atomicrmw sub
94 ull
= __sync_fetch_and_sub (&ull
, 11); // CHECK: atomicrmw sub
96 sc
= __sync_fetch_and_or (&sc
, 11); // CHECK: atomicrmw or
97 uc
= __sync_fetch_and_or (&uc
, 11); // CHECK: atomicrmw or
98 ss
= __sync_fetch_and_or (&ss
, 11); // CHECK: atomicrmw or
99 us
= __sync_fetch_and_or (&us
, 11); // CHECK: atomicrmw or
100 si
= __sync_fetch_and_or (&si
, 11); // CHECK: atomicrmw or
101 ui
= __sync_fetch_and_or (&ui
, 11); // CHECK: atomicrmw or
102 sll
= __sync_fetch_and_or (&sll
, 11); // CHECK: atomicrmw or
103 ull
= __sync_fetch_and_or (&ull
, 11); // CHECK: atomicrmw or
105 sc
= __sync_fetch_and_xor (&sc
, 11); // CHECK: atomicrmw xor
106 uc
= __sync_fetch_and_xor (&uc
, 11); // CHECK: atomicrmw xor
107 ss
= __sync_fetch_and_xor (&ss
, 11); // CHECK: atomicrmw xor
108 us
= __sync_fetch_and_xor (&us
, 11); // CHECK: atomicrmw xor
109 si
= __sync_fetch_and_xor (&si
, 11); // CHECK: atomicrmw xor
110 ui
= __sync_fetch_and_xor (&ui
, 11); // CHECK: atomicrmw xor
111 sll
= __sync_fetch_and_xor (&sll
, 11); // CHECK: atomicrmw xor
112 ull
= __sync_fetch_and_xor (&ull
, 11); // CHECK: atomicrmw xor
114 sc
= __sync_fetch_and_nand (&sc
, 11); // CHECK: atomicrmw nand
115 uc
= __sync_fetch_and_nand (&uc
, 11); // CHECK: atomicrmw nand
116 ss
= __sync_fetch_and_nand (&ss
, 11); // CHECK: atomicrmw nand
117 us
= __sync_fetch_and_nand (&us
, 11); // CHECK: atomicrmw nand
118 si
= __sync_fetch_and_nand (&si
, 11); // CHECK: atomicrmw nand
119 ui
= __sync_fetch_and_nand (&ui
, 11); // CHECK: atomicrmw nand
120 sll
= __sync_fetch_and_nand (&sll
, 11); // CHECK: atomicrmw nand
121 ull
= __sync_fetch_and_nand (&ull
, 11); // CHECK: atomicrmw nand
123 sc
= __sync_fetch_and_and (&sc
, 11); // CHECK: atomicrmw and
124 uc
= __sync_fetch_and_and (&uc
, 11); // CHECK: atomicrmw and
125 ss
= __sync_fetch_and_and (&ss
, 11); // CHECK: atomicrmw and
126 us
= __sync_fetch_and_and (&us
, 11); // CHECK: atomicrmw and
127 si
= __sync_fetch_and_and (&si
, 11); // CHECK: atomicrmw and
128 ui
= __sync_fetch_and_and (&ui
, 11); // CHECK: atomicrmw and
129 sll
= __sync_fetch_and_and (&sll
, 11); // CHECK: atomicrmw and
130 ull
= __sync_fetch_and_and (&ull
, 11); // CHECK: atomicrmw and
134 void test_op_and_fetch (void)
136 sc
= __sync_add_and_fetch (&sc
, uc
); // CHECK: atomicrmw add
137 uc
= __sync_add_and_fetch (&uc
, uc
); // CHECK: atomicrmw add
138 ss
= __sync_add_and_fetch (&ss
, uc
); // CHECK: atomicrmw add
139 us
= __sync_add_and_fetch (&us
, uc
); // CHECK: atomicrmw add
140 si
= __sync_add_and_fetch (&si
, uc
); // CHECK: atomicrmw add
141 ui
= __sync_add_and_fetch (&ui
, uc
); // CHECK: atomicrmw add
142 sll
= __sync_add_and_fetch (&sll
, uc
); // CHECK: atomicrmw add
143 ull
= __sync_add_and_fetch (&ull
, uc
); // CHECK: atomicrmw add
145 sc
= __sync_sub_and_fetch (&sc
, uc
); // CHECK: atomicrmw sub
146 uc
= __sync_sub_and_fetch (&uc
, uc
); // CHECK: atomicrmw sub
147 ss
= __sync_sub_and_fetch (&ss
, uc
); // CHECK: atomicrmw sub
148 us
= __sync_sub_and_fetch (&us
, uc
); // CHECK: atomicrmw sub
149 si
= __sync_sub_and_fetch (&si
, uc
); // CHECK: atomicrmw sub
150 ui
= __sync_sub_and_fetch (&ui
, uc
); // CHECK: atomicrmw sub
151 sll
= __sync_sub_and_fetch (&sll
, uc
); // CHECK: atomicrmw sub
152 ull
= __sync_sub_and_fetch (&ull
, uc
); // CHECK: atomicrmw sub
154 sc
= __sync_or_and_fetch (&sc
, uc
); // CHECK: atomicrmw or
155 uc
= __sync_or_and_fetch (&uc
, uc
); // CHECK: atomicrmw or
156 ss
= __sync_or_and_fetch (&ss
, uc
); // CHECK: atomicrmw or
157 us
= __sync_or_and_fetch (&us
, uc
); // CHECK: atomicrmw or
158 si
= __sync_or_and_fetch (&si
, uc
); // CHECK: atomicrmw or
159 ui
= __sync_or_and_fetch (&ui
, uc
); // CHECK: atomicrmw or
160 sll
= __sync_or_and_fetch (&sll
, uc
); // CHECK: atomicrmw or
161 ull
= __sync_or_and_fetch (&ull
, uc
); // CHECK: atomicrmw or
163 sc
= __sync_xor_and_fetch (&sc
, uc
); // CHECK: atomicrmw xor
164 uc
= __sync_xor_and_fetch (&uc
, uc
); // CHECK: atomicrmw xor
165 ss
= __sync_xor_and_fetch (&ss
, uc
); // CHECK: atomicrmw xor
166 us
= __sync_xor_and_fetch (&us
, uc
); // CHECK: atomicrmw xor
167 si
= __sync_xor_and_fetch (&si
, uc
); // CHECK: atomicrmw xor
168 ui
= __sync_xor_and_fetch (&ui
, uc
); // CHECK: atomicrmw xor
169 sll
= __sync_xor_and_fetch (&sll
, uc
); // CHECK: atomicrmw xor
170 ull
= __sync_xor_and_fetch (&ull
, uc
); // CHECK: atomicrmw xor
172 sc
= __sync_nand_and_fetch (&sc
, uc
); // CHECK: atomicrmw nand
176 uc
= __sync_nand_and_fetch (&uc
, uc
); // CHECK: atomicrmw nand
180 ss
= __sync_nand_and_fetch (&ss
, uc
); // CHECK: atomicrmw nand
184 us
= __sync_nand_and_fetch (&us
, uc
); // CHECK: atomicrmw nand
188 si
= __sync_nand_and_fetch (&si
, uc
); // CHECK: atomicrmw nand
192 ui
= __sync_nand_and_fetch (&ui
, uc
); // CHECK: atomicrmw nand
196 sll
= __sync_nand_and_fetch (&sll
, uc
); // CHECK: atomicrmw nand
200 ull
= __sync_nand_and_fetch (&ull
, uc
); // CHECK: atomicrmw nand
204 u128
= __sync_nand_and_fetch (&u128
, uc
); // CHECK: atomicrmw nand
208 s128
= __sync_nand_and_fetch (&s128
, uc
); // CHECK: atomicrmw nand
213 sc
= __sync_and_and_fetch (&sc
, uc
); // CHECK: atomicrmw and
214 uc
= __sync_and_and_fetch (&uc
, uc
); // CHECK: atomicrmw and
215 ss
= __sync_and_and_fetch (&ss
, uc
); // CHECK: atomicrmw and
216 us
= __sync_and_and_fetch (&us
, uc
); // CHECK: atomicrmw and
217 si
= __sync_and_and_fetch (&si
, uc
); // CHECK: atomicrmw and
218 ui
= __sync_and_and_fetch (&ui
, uc
); // CHECK: atomicrmw and
219 sll
= __sync_and_and_fetch (&sll
, uc
); // CHECK: atomicrmw and
220 ull
= __sync_and_and_fetch (&ull
, uc
); // CHECK: atomicrmw and
224 void test_compare_and_swap (void)
226 sc
= __sync_val_compare_and_swap (&sc
, uc
, sc
);
227 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 1
228 // CHECK: extractvalue { i8, i1 } [[PAIR]], 0
230 uc
= __sync_val_compare_and_swap (&uc
, uc
, sc
);
231 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 1
232 // CHECK: extractvalue { i8, i1 } [[PAIR]], 0
234 ss
= __sync_val_compare_and_swap (&ss
, uc
, sc
);
235 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 2
236 // CHECK: extractvalue { i16, i1 } [[PAIR]], 0
238 us
= __sync_val_compare_and_swap (&us
, uc
, sc
);
239 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 2
240 // CHECK: extractvalue { i16, i1 } [[PAIR]], 0
242 si
= __sync_val_compare_and_swap (&si
, uc
, sc
);
243 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 4
244 // CHECK: extractvalue { i32, i1 } [[PAIR]], 0
246 ui
= __sync_val_compare_and_swap (&ui
, uc
, sc
);
247 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 4
248 // CHECK: extractvalue { i32, i1 } [[PAIR]], 0
250 sll
= __sync_val_compare_and_swap (&sll
, uc
, sc
);
251 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 8
252 // CHECK: extractvalue { i64, i1 } [[PAIR]], 0
254 ull
= __sync_val_compare_and_swap (&ull
, uc
, sc
);
255 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 8
256 // CHECK: extractvalue { i64, i1 } [[PAIR]], 0
259 ui
= __sync_bool_compare_and_swap (&sc
, uc
, sc
);
260 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 1
261 // CHECK: extractvalue { i8, i1 } [[PAIR]], 1
263 ui
= __sync_bool_compare_and_swap (&uc
, uc
, sc
);
264 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 1
265 // CHECK: extractvalue { i8, i1 } [[PAIR]], 1
267 ui
= __sync_bool_compare_and_swap (&ss
, uc
, sc
);
268 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 2
269 // CHECK: extractvalue { i16, i1 } [[PAIR]], 1
271 ui
= __sync_bool_compare_and_swap (&us
, uc
, sc
);
272 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 2
273 // CHECK: extractvalue { i16, i1 } [[PAIR]], 1
275 ui
= __sync_bool_compare_and_swap (&si
, uc
, sc
);
276 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 4
277 // CHECK: extractvalue { i32, i1 } [[PAIR]], 1
279 ui
= __sync_bool_compare_and_swap (&ui
, uc
, sc
);
280 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 4
281 // CHECK: extractvalue { i32, i1 } [[PAIR]], 1
283 ui
= __sync_bool_compare_and_swap (&sll
, uc
, sc
);
284 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 8
285 // CHECK: extractvalue { i64, i1 } [[PAIR]], 1
287 ui
= __sync_bool_compare_and_swap (&ull
, uc
, sc
);
288 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg ptr {{.*}} seq_cst, align 8
289 // CHECK: extractvalue { i64, i1 } [[PAIR]], 1
292 void test_lock (void)
294 sc
= __sync_lock_test_and_set (&sc
, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 1
295 uc
= __sync_lock_test_and_set (&uc
, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 1
296 ss
= __sync_lock_test_and_set (&ss
, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 2
297 us
= __sync_lock_test_and_set (&us
, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 2
298 si
= __sync_lock_test_and_set (&si
, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 4
299 ui
= __sync_lock_test_and_set (&ui
, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 4
300 sll
= __sync_lock_test_and_set (&sll
, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 8
301 ull
= __sync_lock_test_and_set (&ull
, 1); // CHECK: atomicrmw xchg ptr {{.*}} seq_cst, align 8
303 __sync_synchronize (); // CHECK: fence seq_cst
305 __sync_lock_release (&sc
); // CHECK: store atomic {{.*}} release, align 1
306 __sync_lock_release (&uc
); // CHECK: store atomic {{.*}} release, align 1
307 __sync_lock_release (&ss
); // CHECK: store atomic {{.*}} release, align 2
308 __sync_lock_release (&us
); /// CHECK: store atomic {{.*}} release, align 2
309 __sync_lock_release (&si
); // CHECK: store atomic {{.*}} release, align 4
310 __sync_lock_release (&ui
); // CHECK: store atomic {{.*}} release, align 4
311 __sync_lock_release (&sll
); // CHECK: store atomic {{.*}} release, align 8
312 __sync_lock_release (&ull
); // CHECK: store atomic {{.*}} release, align 8
315 void test_atomic(void) {
316 ui
= __atomic_fetch_min(&ui
, 5, __ATOMIC_RELAXED
); // CHECK: atomicrmw umin {{.*}} monotonic, align 4
317 si
= __atomic_fetch_min(&si
, 5, __ATOMIC_SEQ_CST
); // CHECK: atomicrmw min {{.*}} seq_cst, align 4
318 ui
= __atomic_fetch_max(&ui
, 5, __ATOMIC_ACQUIRE
); // CHECK: atomicrmw umax {{.*}} acquire, align 4
319 si
= __atomic_fetch_max(&si
, 5, __ATOMIC_RELEASE
); // CHECK: atomicrmw max {{.*}} release, align 4