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 4 5 signed char sc; 6 unsigned char uc; 7 signed short ss; 8 unsigned short us; 9 signed int si; 10 unsigned int ui; 11 signed long long sll; 12 unsigned long long ull; 13 14 void test_op_ignore (void) // CHECK-LABEL: define void @test_op_ignore 15 { 16 (void) __sync_fetch_and_add (&sc, 1); // CHECK: atomicrmw add i8 17 (void) __sync_fetch_and_add (&uc, 1); // CHECK: atomicrmw add i8 18 (void) __sync_fetch_and_add (&ss, 1); // CHECK: atomicrmw add i16 19 (void) __sync_fetch_and_add (&us, 1); // CHECK: atomicrmw add i16 20 (void) __sync_fetch_and_add (&si, 1); // CHECK: atomicrmw add i32 21 (void) __sync_fetch_and_add (&ui, 1); // CHECK: atomicrmw add i32 22 (void) __sync_fetch_and_add (&sll, 1); // CHECK: atomicrmw add i64 23 (void) __sync_fetch_and_add (&ull, 1); // CHECK: atomicrmw add i64 24 25 (void) __sync_fetch_and_sub (&sc, 1); // CHECK: atomicrmw sub i8 26 (void) __sync_fetch_and_sub (&uc, 1); // CHECK: atomicrmw sub i8 27 (void) __sync_fetch_and_sub (&ss, 1); // CHECK: atomicrmw sub i16 28 (void) __sync_fetch_and_sub (&us, 1); // CHECK: atomicrmw sub i16 29 (void) __sync_fetch_and_sub (&si, 1); // CHECK: atomicrmw sub i32 30 (void) __sync_fetch_and_sub (&ui, 1); // CHECK: atomicrmw sub i32 31 (void) __sync_fetch_and_sub (&sll, 1); // CHECK: atomicrmw sub i64 32 (void) __sync_fetch_and_sub (&ull, 1); // CHECK: atomicrmw sub i64 33 34 (void) __sync_fetch_and_or (&sc, 1); // CHECK: atomicrmw or i8 35 (void) __sync_fetch_and_or (&uc, 1); // CHECK: atomicrmw or i8 36 (void) __sync_fetch_and_or (&ss, 1); // CHECK: atomicrmw or i16 37 (void) __sync_fetch_and_or (&us, 1); // CHECK: atomicrmw or i16 38 (void) __sync_fetch_and_or (&si, 1); // CHECK: atomicrmw or i32 39 (void) __sync_fetch_and_or (&ui, 1); // CHECK: atomicrmw or i32 40 (void) __sync_fetch_and_or (&sll, 1); // CHECK: atomicrmw or i64 41 (void) __sync_fetch_and_or (&ull, 1); // CHECK: atomicrmw or i64 42 43 (void) __sync_fetch_and_xor (&sc, 1); // CHECK: atomicrmw xor i8 44 (void) __sync_fetch_and_xor (&uc, 1); // CHECK: atomicrmw xor i8 45 (void) __sync_fetch_and_xor (&ss, 1); // CHECK: atomicrmw xor i16 46 (void) __sync_fetch_and_xor (&us, 1); // CHECK: atomicrmw xor i16 47 (void) __sync_fetch_and_xor (&si, 1); // CHECK: atomicrmw xor i32 48 (void) __sync_fetch_and_xor (&ui, 1); // CHECK: atomicrmw xor i32 49 (void) __sync_fetch_and_xor (&sll, 1); // CHECK: atomicrmw xor i64 50 (void) __sync_fetch_and_xor (&ull, 1); // CHECK: atomicrmw xor i64 51 52 (void) __sync_fetch_and_nand (&sc, 1); // CHECK: atomicrmw nand i8 53 (void) __sync_fetch_and_nand (&uc, 1); // CHECK: atomicrmw nand i8 54 (void) __sync_fetch_and_nand (&ss, 1); // CHECK: atomicrmw nand i16 55 (void) __sync_fetch_and_nand (&us, 1); // CHECK: atomicrmw nand i16 56 (void) __sync_fetch_and_nand (&si, 1); // CHECK: atomicrmw nand i32 57 (void) __sync_fetch_and_nand (&ui, 1); // CHECK: atomicrmw nand i32 58 (void) __sync_fetch_and_nand (&sll, 1); // CHECK: atomicrmw nand i64 59 (void) __sync_fetch_and_nand (&ull, 1); // CHECK: atomicrmw nand i64 60 61 (void) __sync_fetch_and_and (&sc, 1); // CHECK: atomicrmw and i8 62 (void) __sync_fetch_and_and (&uc, 1); // CHECK: atomicrmw and i8 63 (void) __sync_fetch_and_and (&ss, 1); // CHECK: atomicrmw and i16 64 (void) __sync_fetch_and_and (&us, 1); // CHECK: atomicrmw and i16 65 (void) __sync_fetch_and_and (&si, 1); // CHECK: atomicrmw and i32 66 (void) __sync_fetch_and_and (&ui, 1); // CHECK: atomicrmw and i32 67 (void) __sync_fetch_and_and (&sll, 1); // CHECK: atomicrmw and i64 68 (void) __sync_fetch_and_and (&ull, 1); // CHECK: atomicrmw and i64 69 70 } 71 72 void test_fetch_and_op (void) // CHECK-LABEL: define void @test_fetch_and_op 73 { 74 sc = __sync_fetch_and_add (&sc, 11); // CHECK: atomicrmw add 75 uc = __sync_fetch_and_add (&uc, 11); // CHECK: atomicrmw add 76 ss = __sync_fetch_and_add (&ss, 11); // CHECK: atomicrmw add 77 us = __sync_fetch_and_add (&us, 11); // CHECK: atomicrmw add 78 si = __sync_fetch_and_add (&si, 11); // CHECK: atomicrmw add 79 ui = __sync_fetch_and_add (&ui, 11); // CHECK: atomicrmw add 80 sll = __sync_fetch_and_add (&sll, 11); // CHECK: atomicrmw add 81 ull = __sync_fetch_and_add (&ull, 11); // CHECK: atomicrmw add 82 83 sc = __sync_fetch_and_sub (&sc, 11); // CHECK: atomicrmw sub 84 uc = __sync_fetch_and_sub (&uc, 11); // CHECK: atomicrmw sub 85 ss = __sync_fetch_and_sub (&ss, 11); // CHECK: atomicrmw sub 86 us = __sync_fetch_and_sub (&us, 11); // CHECK: atomicrmw sub 87 si = __sync_fetch_and_sub (&si, 11); // CHECK: atomicrmw sub 88 ui = __sync_fetch_and_sub (&ui, 11); // CHECK: atomicrmw sub 89 sll = __sync_fetch_and_sub (&sll, 11); // CHECK: atomicrmw sub 90 ull = __sync_fetch_and_sub (&ull, 11); // CHECK: atomicrmw sub 91 92 sc = __sync_fetch_and_or (&sc, 11); // CHECK: atomicrmw or 93 uc = __sync_fetch_and_or (&uc, 11); // CHECK: atomicrmw or 94 ss = __sync_fetch_and_or (&ss, 11); // CHECK: atomicrmw or 95 us = __sync_fetch_and_or (&us, 11); // CHECK: atomicrmw or 96 si = __sync_fetch_and_or (&si, 11); // CHECK: atomicrmw or 97 ui = __sync_fetch_and_or (&ui, 11); // CHECK: atomicrmw or 98 sll = __sync_fetch_and_or (&sll, 11); // CHECK: atomicrmw or 99 ull = __sync_fetch_and_or (&ull, 11); // CHECK: atomicrmw or 100 101 sc = __sync_fetch_and_xor (&sc, 11); // CHECK: atomicrmw xor 102 uc = __sync_fetch_and_xor (&uc, 11); // CHECK: atomicrmw xor 103 ss = __sync_fetch_and_xor (&ss, 11); // CHECK: atomicrmw xor 104 us = __sync_fetch_and_xor (&us, 11); // CHECK: atomicrmw xor 105 si = __sync_fetch_and_xor (&si, 11); // CHECK: atomicrmw xor 106 ui = __sync_fetch_and_xor (&ui, 11); // CHECK: atomicrmw xor 107 sll = __sync_fetch_and_xor (&sll, 11); // CHECK: atomicrmw xor 108 ull = __sync_fetch_and_xor (&ull, 11); // CHECK: atomicrmw xor 109 110 sc = __sync_fetch_and_nand (&sc, 11); // CHECK: atomicrmw nand 111 uc = __sync_fetch_and_nand (&uc, 11); // CHECK: atomicrmw nand 112 ss = __sync_fetch_and_nand (&ss, 11); // CHECK: atomicrmw nand 113 us = __sync_fetch_and_nand (&us, 11); // CHECK: atomicrmw nand 114 si = __sync_fetch_and_nand (&si, 11); // CHECK: atomicrmw nand 115 ui = __sync_fetch_and_nand (&ui, 11); // CHECK: atomicrmw nand 116 sll = __sync_fetch_and_nand (&sll, 11); // CHECK: atomicrmw nand 117 ull = __sync_fetch_and_nand (&ull, 11); // CHECK: atomicrmw nand 118 119 sc = __sync_fetch_and_and (&sc, 11); // CHECK: atomicrmw and 120 uc = __sync_fetch_and_and (&uc, 11); // CHECK: atomicrmw and 121 ss = __sync_fetch_and_and (&ss, 11); // CHECK: atomicrmw and 122 us = __sync_fetch_and_and (&us, 11); // CHECK: atomicrmw and 123 si = __sync_fetch_and_and (&si, 11); // CHECK: atomicrmw and 124 ui = __sync_fetch_and_and (&ui, 11); // CHECK: atomicrmw and 125 sll = __sync_fetch_and_and (&sll, 11); // CHECK: atomicrmw and 126 ull = __sync_fetch_and_and (&ull, 11); // CHECK: atomicrmw and 127 128 } 129 130 void test_op_and_fetch (void) 131 { 132 sc = __sync_add_and_fetch (&sc, uc); // CHECK: atomicrmw add 133 uc = __sync_add_and_fetch (&uc, uc); // CHECK: atomicrmw add 134 ss = __sync_add_and_fetch (&ss, uc); // CHECK: atomicrmw add 135 us = __sync_add_and_fetch (&us, uc); // CHECK: atomicrmw add 136 si = __sync_add_and_fetch (&si, uc); // CHECK: atomicrmw add 137 ui = __sync_add_and_fetch (&ui, uc); // CHECK: atomicrmw add 138 sll = __sync_add_and_fetch (&sll, uc); // CHECK: atomicrmw add 139 ull = __sync_add_and_fetch (&ull, uc); // CHECK: atomicrmw add 140 141 sc = __sync_sub_and_fetch (&sc, uc); // CHECK: atomicrmw sub 142 uc = __sync_sub_and_fetch (&uc, uc); // CHECK: atomicrmw sub 143 ss = __sync_sub_and_fetch (&ss, uc); // CHECK: atomicrmw sub 144 us = __sync_sub_and_fetch (&us, uc); // CHECK: atomicrmw sub 145 si = __sync_sub_and_fetch (&si, uc); // CHECK: atomicrmw sub 146 ui = __sync_sub_and_fetch (&ui, uc); // CHECK: atomicrmw sub 147 sll = __sync_sub_and_fetch (&sll, uc); // CHECK: atomicrmw sub 148 ull = __sync_sub_and_fetch (&ull, uc); // CHECK: atomicrmw sub 149 150 sc = __sync_or_and_fetch (&sc, uc); // CHECK: atomicrmw or 151 uc = __sync_or_and_fetch (&uc, uc); // CHECK: atomicrmw or 152 ss = __sync_or_and_fetch (&ss, uc); // CHECK: atomicrmw or 153 us = __sync_or_and_fetch (&us, uc); // CHECK: atomicrmw or 154 si = __sync_or_and_fetch (&si, uc); // CHECK: atomicrmw or 155 ui = __sync_or_and_fetch (&ui, uc); // CHECK: atomicrmw or 156 sll = __sync_or_and_fetch (&sll, uc); // CHECK: atomicrmw or 157 ull = __sync_or_and_fetch (&ull, uc); // CHECK: atomicrmw or 158 159 sc = __sync_xor_and_fetch (&sc, uc); // CHECK: atomicrmw xor 160 uc = __sync_xor_and_fetch (&uc, uc); // CHECK: atomicrmw xor 161 ss = __sync_xor_and_fetch (&ss, uc); // CHECK: atomicrmw xor 162 us = __sync_xor_and_fetch (&us, uc); // CHECK: atomicrmw xor 163 si = __sync_xor_and_fetch (&si, uc); // CHECK: atomicrmw xor 164 ui = __sync_xor_and_fetch (&ui, uc); // CHECK: atomicrmw xor 165 sll = __sync_xor_and_fetch (&sll, uc); // CHECK: atomicrmw xor 166 ull = __sync_xor_and_fetch (&ull, uc); // CHECK: atomicrmw xor 167 168 sc = __sync_nand_and_fetch (&sc, uc); // CHECK: atomicrmw nand 169 // CHECK: and 170 // CHECK: xor 171 uc = __sync_nand_and_fetch (&uc, uc); // CHECK: atomicrmw nand 172 // CHECK: and 173 // CHECK: xor 174 ss = __sync_nand_and_fetch (&ss, uc); // CHECK: atomicrmw nand 175 // CHECK: and 176 // CHECK: xor 177 us = __sync_nand_and_fetch (&us, uc); // CHECK: atomicrmw nand 178 // CHECK: and 179 // CHECK: xor 180 si = __sync_nand_and_fetch (&si, uc); // CHECK: atomicrmw nand 181 // CHECK: and 182 // CHECK: xor 183 ui = __sync_nand_and_fetch (&ui, uc); // CHECK: atomicrmw nand 184 // CHECK: and 185 // CHECK: xor 186 sll = __sync_nand_and_fetch (&sll, uc); // CHECK: atomicrmw nand 187 // CHECK: and 188 // CHECK: xor 189 ull = __sync_nand_and_fetch (&ull, uc); // CHECK: atomicrmw nand 190 // CHECK: and 191 // CHECK: xor 192 193 sc = __sync_and_and_fetch (&sc, uc); // CHECK: atomicrmw and 194 uc = __sync_and_and_fetch (&uc, uc); // CHECK: atomicrmw and 195 ss = __sync_and_and_fetch (&ss, uc); // CHECK: atomicrmw and 196 us = __sync_and_and_fetch (&us, uc); // CHECK: atomicrmw and 197 si = __sync_and_and_fetch (&si, uc); // CHECK: atomicrmw and 198 ui = __sync_and_and_fetch (&ui, uc); // CHECK: atomicrmw and 199 sll = __sync_and_and_fetch (&sll, uc); // CHECK: atomicrmw and 200 ull = __sync_and_and_fetch (&ull, uc); // CHECK: atomicrmw and 201 202 } 203 204 void test_compare_and_swap (void) 205 { 206 sc = __sync_val_compare_and_swap (&sc, uc, sc); 207 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8 208 // CHECK: extractvalue { i8, i1 } [[PAIR]], 0 209 210 uc = __sync_val_compare_and_swap (&uc, uc, sc); 211 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8 212 // CHECK: extractvalue { i8, i1 } [[PAIR]], 0 213 214 ss = __sync_val_compare_and_swap (&ss, uc, sc); 215 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16 216 // CHECK: extractvalue { i16, i1 } [[PAIR]], 0 217 218 us = __sync_val_compare_and_swap (&us, uc, sc); 219 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16 220 // CHECK: extractvalue { i16, i1 } [[PAIR]], 0 221 222 si = __sync_val_compare_and_swap (&si, uc, sc); 223 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32 224 // CHECK: extractvalue { i32, i1 } [[PAIR]], 0 225 226 ui = __sync_val_compare_and_swap (&ui, uc, sc); 227 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32 228 // CHECK: extractvalue { i32, i1 } [[PAIR]], 0 229 230 sll = __sync_val_compare_and_swap (&sll, uc, sc); 231 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64 232 // CHECK: extractvalue { i64, i1 } [[PAIR]], 0 233 234 ull = __sync_val_compare_and_swap (&ull, uc, sc); 235 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64 236 // CHECK: extractvalue { i64, i1 } [[PAIR]], 0 237 238 239 ui = __sync_bool_compare_and_swap (&sc, uc, sc); 240 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8 241 // CHECK: extractvalue { i8, i1 } [[PAIR]], 1 242 243 ui = __sync_bool_compare_and_swap (&uc, uc, sc); 244 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i8 245 // CHECK: extractvalue { i8, i1 } [[PAIR]], 1 246 247 ui = __sync_bool_compare_and_swap (&ss, uc, sc); 248 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16 249 // CHECK: extractvalue { i16, i1 } [[PAIR]], 1 250 251 ui = __sync_bool_compare_and_swap (&us, uc, sc); 252 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i16 253 // CHECK: extractvalue { i16, i1 } [[PAIR]], 1 254 255 ui = __sync_bool_compare_and_swap (&si, uc, sc); 256 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32 257 // CHECK: extractvalue { i32, i1 } [[PAIR]], 1 258 259 ui = __sync_bool_compare_and_swap (&ui, uc, sc); 260 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i32 261 // CHECK: extractvalue { i32, i1 } [[PAIR]], 1 262 263 ui = __sync_bool_compare_and_swap (&sll, uc, sc); 264 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64 265 // CHECK: extractvalue { i64, i1 } [[PAIR]], 1 266 267 ui = __sync_bool_compare_and_swap (&ull, uc, sc); 268 // CHECK: [[PAIR:%[a-z0-9._]+]] = cmpxchg i64 269 // CHECK: extractvalue { i64, i1 } [[PAIR]], 1 270 } 271 272 void test_lock (void) 273 { 274 sc = __sync_lock_test_and_set (&sc, 1); // CHECK: atomicrmw xchg i8 275 uc = __sync_lock_test_and_set (&uc, 1); // CHECK: atomicrmw xchg i8 276 ss = __sync_lock_test_and_set (&ss, 1); // CHECK: atomicrmw xchg i16 277 us = __sync_lock_test_and_set (&us, 1); // CHECK: atomicrmw xchg i16 278 si = __sync_lock_test_and_set (&si, 1); // CHECK: atomicrmw xchg i32 279 ui = __sync_lock_test_and_set (&ui, 1); // CHECK: atomicrmw xchg i32 280 sll = __sync_lock_test_and_set (&sll, 1); // CHECK: atomicrmw xchg i64 281 ull = __sync_lock_test_and_set (&ull, 1); // CHECK: atomicrmw xchg i64 282 283 __sync_synchronize (); // CHECK: fence seq_cst 284 285 __sync_lock_release (&sc); // CHECK: store atomic {{.*}} release, align 1 286 __sync_lock_release (&uc); // CHECK: store atomic {{.*}} release, align 1 287 __sync_lock_release (&ss); // CHECK: store atomic {{.*}} release, align 2 288 __sync_lock_release (&us); /// CHECK: store atomic {{.*}} release, align 2 289 __sync_lock_release (&si); // CHECK: store atomic {{.*}} release, align 4 290 __sync_lock_release (&ui); // CHECK: store atomic {{.*}} release, align 4 291 __sync_lock_release (&sll); // CHECK: store atomic {{.*}} release, align 8 292 __sync_lock_release (&ull); // CHECK: store atomic {{.*}} release, align 8 293 } 294