1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2 ; RUN: llc < %s -mtriple=x86_64-apple-macosx10.9 -verify-machineinstrs -mattr=cx16 | FileCheck %s 3 4 @var = global i128 0 5 6 ; Due to the scheduling right after isel for cmpxchg and given the 7 ; machine scheduler and copy coalescer do not mess up with physical 8 ; register live-ranges, we end up with a useless copy. 9 define i128 @val_compare_and_swap(i128* %p, i128 %oldval, i128 %newval) { 10 ; CHECK-LABEL: val_compare_and_swap: 11 ; CHECK: ## %bb.0: 12 ; CHECK-NEXT: pushq %rbx 13 ; CHECK-NEXT: .cfi_def_cfa_offset 16 14 ; CHECK-NEXT: .cfi_offset %rbx, -16 15 ; CHECK-NEXT: movq %rcx, %r9 16 ; CHECK-NEXT: movq %rsi, %rax 17 ; CHECK-NEXT: movq %r8, %rcx 18 ; CHECK-NEXT: movq %r9, %rbx 19 ; CHECK-NEXT: lock cmpxchg16b (%rdi) 20 ; CHECK-NEXT: popq %rbx 21 ; CHECK-NEXT: retq 22 %pair = cmpxchg i128* %p, i128 %oldval, i128 %newval acquire acquire 23 %val = extractvalue { i128, i1 } %pair, 0 24 ret i128 %val 25 } 26 27 define void @fetch_and_nand(i128* %p, i128 %bits) { 28 ; CHECK-LABEL: fetch_and_nand: 29 ; CHECK: ## %bb.0: 30 ; CHECK-NEXT: pushq %rbx 31 ; CHECK-NEXT: .cfi_def_cfa_offset 16 32 ; CHECK-NEXT: .cfi_offset %rbx, -16 33 ; CHECK-NEXT: movq %rdx, %r8 34 ; CHECK-NEXT: movq (%rdi), %rax 35 ; CHECK-NEXT: movq 8(%rdi), %rdx 36 ; CHECK-NEXT: .p2align 4, 0x90 37 ; CHECK-NEXT: LBB1_1: ## %atomicrmw.start 38 ; CHECK-NEXT: ## =>This Inner Loop Header: Depth=1 39 ; CHECK-NEXT: movq %rdx, %rcx 40 ; CHECK-NEXT: andq %r8, %rcx 41 ; CHECK-NEXT: movq %rax, %rbx 42 ; CHECK-NEXT: andq %rsi, %rbx 43 ; CHECK-NEXT: notq %rbx 44 ; CHECK-NEXT: notq %rcx 45 ; CHECK-NEXT: lock cmpxchg16b (%rdi) 46 ; CHECK-NEXT: jne LBB1_1 47 ; CHECK-NEXT: ## %bb.2: ## %atomicrmw.end 48 ; CHECK-NEXT: movq %rax, {{.*}}(%rip) 49 ; CHECK-NEXT: movq %rdx, _var+{{.*}}(%rip) 50 ; CHECK-NEXT: popq %rbx 51 ; CHECK-NEXT: retq 52 %val = atomicrmw nand i128* %p, i128 %bits release 53 store i128 %val, i128* @var, align 16 54 ret void 55 } 56 57 define void @fetch_and_or(i128* %p, i128 %bits) { 58 ; CHECK-LABEL: fetch_and_or: 59 ; CHECK: ## %bb.0: 60 ; CHECK-NEXT: pushq %rbx 61 ; CHECK-NEXT: .cfi_def_cfa_offset 16 62 ; CHECK-NEXT: .cfi_offset %rbx, -16 63 ; CHECK-NEXT: movq %rdx, %r8 64 ; CHECK-NEXT: movq (%rdi), %rax 65 ; CHECK-NEXT: movq 8(%rdi), %rdx 66 ; CHECK-NEXT: .p2align 4, 0x90 67 ; CHECK-NEXT: LBB2_1: ## %atomicrmw.start 68 ; CHECK-NEXT: ## =>This Inner Loop Header: Depth=1 69 ; CHECK-NEXT: movq %rax, %rbx 70 ; CHECK-NEXT: orq %rsi, %rbx 71 ; CHECK-NEXT: movq %rdx, %rcx 72 ; CHECK-NEXT: orq %r8, %rcx 73 ; CHECK-NEXT: lock cmpxchg16b (%rdi) 74 ; CHECK-NEXT: jne LBB2_1 75 ; CHECK-NEXT: ## %bb.2: ## %atomicrmw.end 76 ; CHECK-NEXT: movq %rax, {{.*}}(%rip) 77 ; CHECK-NEXT: movq %rdx, _var+{{.*}}(%rip) 78 ; CHECK-NEXT: popq %rbx 79 ; CHECK-NEXT: retq 80 %val = atomicrmw or i128* %p, i128 %bits seq_cst 81 store i128 %val, i128* @var, align 16 82 ret void 83 } 84 85 define void @fetch_and_add(i128* %p, i128 %bits) { 86 ; CHECK-LABEL: fetch_and_add: 87 ; CHECK: ## %bb.0: 88 ; CHECK-NEXT: pushq %rbx 89 ; CHECK-NEXT: .cfi_def_cfa_offset 16 90 ; CHECK-NEXT: .cfi_offset %rbx, -16 91 ; CHECK-NEXT: movq %rdx, %r8 92 ; CHECK-NEXT: movq (%rdi), %rax 93 ; CHECK-NEXT: movq 8(%rdi), %rdx 94 ; CHECK-NEXT: .p2align 4, 0x90 95 ; CHECK-NEXT: LBB3_1: ## %atomicrmw.start 96 ; CHECK-NEXT: ## =>This Inner Loop Header: Depth=1 97 ; CHECK-NEXT: movq %rax, %rbx 98 ; CHECK-NEXT: addq %rsi, %rbx 99 ; CHECK-NEXT: movq %rdx, %rcx 100 ; CHECK-NEXT: adcq %r8, %rcx 101 ; CHECK-NEXT: lock cmpxchg16b (%rdi) 102 ; CHECK-NEXT: jne LBB3_1 103 ; CHECK-NEXT: ## %bb.2: ## %atomicrmw.end 104 ; CHECK-NEXT: movq %rax, {{.*}}(%rip) 105 ; CHECK-NEXT: movq %rdx, _var+{{.*}}(%rip) 106 ; CHECK-NEXT: popq %rbx 107 ; CHECK-NEXT: retq 108 %val = atomicrmw add i128* %p, i128 %bits seq_cst 109 store i128 %val, i128* @var, align 16 110 ret void 111 } 112 113 define void @fetch_and_sub(i128* %p, i128 %bits) { 114 ; CHECK-LABEL: fetch_and_sub: 115 ; CHECK: ## %bb.0: 116 ; CHECK-NEXT: pushq %rbx 117 ; CHECK-NEXT: .cfi_def_cfa_offset 16 118 ; CHECK-NEXT: .cfi_offset %rbx, -16 119 ; CHECK-NEXT: movq %rdx, %r8 120 ; CHECK-NEXT: movq (%rdi), %rax 121 ; CHECK-NEXT: movq 8(%rdi), %rdx 122 ; CHECK-NEXT: .p2align 4, 0x90 123 ; CHECK-NEXT: LBB4_1: ## %atomicrmw.start 124 ; CHECK-NEXT: ## =>This Inner Loop Header: Depth=1 125 ; CHECK-NEXT: movq %rax, %rbx 126 ; CHECK-NEXT: subq %rsi, %rbx 127 ; CHECK-NEXT: movq %rdx, %rcx 128 ; CHECK-NEXT: sbbq %r8, %rcx 129 ; CHECK-NEXT: lock cmpxchg16b (%rdi) 130 ; CHECK-NEXT: jne LBB4_1 131 ; CHECK-NEXT: ## %bb.2: ## %atomicrmw.end 132 ; CHECK-NEXT: movq %rax, {{.*}}(%rip) 133 ; CHECK-NEXT: movq %rdx, _var+{{.*}}(%rip) 134 ; CHECK-NEXT: popq %rbx 135 ; CHECK-NEXT: retq 136 %val = atomicrmw sub i128* %p, i128 %bits seq_cst 137 store i128 %val, i128* @var, align 16 138 ret void 139 } 140 141 define void @fetch_and_min(i128* %p, i128 %bits) { 142 ; CHECK-LABEL: fetch_and_min: 143 ; CHECK: ## %bb.0: 144 ; CHECK-NEXT: pushq %rbx 145 ; CHECK-NEXT: .cfi_def_cfa_offset 16 146 ; CHECK-NEXT: .cfi_offset %rbx, -16 147 ; CHECK-NEXT: movq %rdx, %r8 148 ; CHECK-NEXT: movq (%rdi), %rax 149 ; CHECK-NEXT: movq 8(%rdi), %rdx 150 ; CHECK-NEXT: .p2align 4, 0x90 151 ; CHECK-NEXT: LBB5_1: ## %atomicrmw.start 152 ; CHECK-NEXT: ## =>This Inner Loop Header: Depth=1 153 ; CHECK-NEXT: cmpq %rax, %rsi 154 ; CHECK-NEXT: movq %r8, %rcx 155 ; CHECK-NEXT: sbbq %rdx, %rcx 156 ; CHECK-NEXT: movq %r8, %rcx 157 ; CHECK-NEXT: cmovgeq %rdx, %rcx 158 ; CHECK-NEXT: movq %rsi, %rbx 159 ; CHECK-NEXT: cmovgeq %rax, %rbx 160 ; CHECK-NEXT: lock cmpxchg16b (%rdi) 161 ; CHECK-NEXT: jne LBB5_1 162 ; CHECK-NEXT: ## %bb.2: ## %atomicrmw.end 163 ; CHECK-NEXT: movq %rax, {{.*}}(%rip) 164 ; CHECK-NEXT: movq %rdx, _var+{{.*}}(%rip) 165 ; CHECK-NEXT: popq %rbx 166 ; CHECK-NEXT: retq 167 %val = atomicrmw min i128* %p, i128 %bits seq_cst 168 store i128 %val, i128* @var, align 16 169 ret void 170 } 171 172 define void @fetch_and_max(i128* %p, i128 %bits) { 173 ; CHECK-LABEL: fetch_and_max: 174 ; CHECK: ## %bb.0: 175 ; CHECK-NEXT: pushq %rbx 176 ; CHECK-NEXT: .cfi_def_cfa_offset 16 177 ; CHECK-NEXT: .cfi_offset %rbx, -16 178 ; CHECK-NEXT: movq %rdx, %r8 179 ; CHECK-NEXT: movq (%rdi), %rax 180 ; CHECK-NEXT: movq 8(%rdi), %rdx 181 ; CHECK-NEXT: .p2align 4, 0x90 182 ; CHECK-NEXT: LBB6_1: ## %atomicrmw.start 183 ; CHECK-NEXT: ## =>This Inner Loop Header: Depth=1 184 ; CHECK-NEXT: cmpq %rsi, %rax 185 ; CHECK-NEXT: movq %rdx, %rcx 186 ; CHECK-NEXT: sbbq %r8, %rcx 187 ; CHECK-NEXT: movq %r8, %rcx 188 ; CHECK-NEXT: cmovgeq %rdx, %rcx 189 ; CHECK-NEXT: movq %rsi, %rbx 190 ; CHECK-NEXT: cmovgeq %rax, %rbx 191 ; CHECK-NEXT: lock cmpxchg16b (%rdi) 192 ; CHECK-NEXT: jne LBB6_1 193 ; CHECK-NEXT: ## %bb.2: ## %atomicrmw.end 194 ; CHECK-NEXT: movq %rax, {{.*}}(%rip) 195 ; CHECK-NEXT: movq %rdx, _var+{{.*}}(%rip) 196 ; CHECK-NEXT: popq %rbx 197 ; CHECK-NEXT: retq 198 %val = atomicrmw max i128* %p, i128 %bits seq_cst 199 store i128 %val, i128* @var, align 16 200 ret void 201 } 202 203 define void @fetch_and_umin(i128* %p, i128 %bits) { 204 ; CHECK-LABEL: fetch_and_umin: 205 ; CHECK: ## %bb.0: 206 ; CHECK-NEXT: pushq %rbx 207 ; CHECK-NEXT: .cfi_def_cfa_offset 16 208 ; CHECK-NEXT: .cfi_offset %rbx, -16 209 ; CHECK-NEXT: movq %rdx, %r8 210 ; CHECK-NEXT: movq (%rdi), %rax 211 ; CHECK-NEXT: movq 8(%rdi), %rdx 212 ; CHECK-NEXT: .p2align 4, 0x90 213 ; CHECK-NEXT: LBB7_1: ## %atomicrmw.start 214 ; CHECK-NEXT: ## =>This Inner Loop Header: Depth=1 215 ; CHECK-NEXT: cmpq %rax, %rsi 216 ; CHECK-NEXT: movq %r8, %rcx 217 ; CHECK-NEXT: sbbq %rdx, %rcx 218 ; CHECK-NEXT: movq %r8, %rcx 219 ; CHECK-NEXT: cmovaeq %rdx, %rcx 220 ; CHECK-NEXT: movq %rsi, %rbx 221 ; CHECK-NEXT: cmovaeq %rax, %rbx 222 ; CHECK-NEXT: lock cmpxchg16b (%rdi) 223 ; CHECK-NEXT: jne LBB7_1 224 ; CHECK-NEXT: ## %bb.2: ## %atomicrmw.end 225 ; CHECK-NEXT: movq %rax, {{.*}}(%rip) 226 ; CHECK-NEXT: movq %rdx, _var+{{.*}}(%rip) 227 ; CHECK-NEXT: popq %rbx 228 ; CHECK-NEXT: retq 229 %val = atomicrmw umin i128* %p, i128 %bits seq_cst 230 store i128 %val, i128* @var, align 16 231 ret void 232 } 233 234 define void @fetch_and_umax(i128* %p, i128 %bits) { 235 ; CHECK-LABEL: fetch_and_umax: 236 ; CHECK: ## %bb.0: 237 ; CHECK-NEXT: pushq %rbx 238 ; CHECK-NEXT: .cfi_def_cfa_offset 16 239 ; CHECK-NEXT: .cfi_offset %rbx, -16 240 ; CHECK-NEXT: movq %rdx, %r8 241 ; CHECK-NEXT: movq (%rdi), %rax 242 ; CHECK-NEXT: movq 8(%rdi), %rdx 243 ; CHECK-NEXT: .p2align 4, 0x90 244 ; CHECK-NEXT: LBB8_1: ## %atomicrmw.start 245 ; CHECK-NEXT: ## =>This Inner Loop Header: Depth=1 246 ; CHECK-NEXT: cmpq %rax, %rsi 247 ; CHECK-NEXT: movq %r8, %rcx 248 ; CHECK-NEXT: sbbq %rdx, %rcx 249 ; CHECK-NEXT: movq %r8, %rcx 250 ; CHECK-NEXT: cmovbq %rdx, %rcx 251 ; CHECK-NEXT: movq %rsi, %rbx 252 ; CHECK-NEXT: cmovbq %rax, %rbx 253 ; CHECK-NEXT: lock cmpxchg16b (%rdi) 254 ; CHECK-NEXT: jne LBB8_1 255 ; CHECK-NEXT: ## %bb.2: ## %atomicrmw.end 256 ; CHECK-NEXT: movq %rax, {{.*}}(%rip) 257 ; CHECK-NEXT: movq %rdx, _var+{{.*}}(%rip) 258 ; CHECK-NEXT: popq %rbx 259 ; CHECK-NEXT: retq 260 %val = atomicrmw umax i128* %p, i128 %bits seq_cst 261 store i128 %val, i128* @var, align 16 262 ret void 263 } 264 265 define i128 @atomic_load_seq_cst(i128* %p) { 266 ; CHECK-LABEL: atomic_load_seq_cst: 267 ; CHECK: ## %bb.0: 268 ; CHECK-NEXT: pushq %rbx 269 ; CHECK-NEXT: .cfi_def_cfa_offset 16 270 ; CHECK-NEXT: .cfi_offset %rbx, -16 271 ; CHECK-NEXT: xorl %eax, %eax 272 ; CHECK-NEXT: xorl %edx, %edx 273 ; CHECK-NEXT: xorl %ecx, %ecx 274 ; CHECK-NEXT: xorl %ebx, %ebx 275 ; CHECK-NEXT: lock cmpxchg16b (%rdi) 276 ; CHECK-NEXT: popq %rbx 277 ; CHECK-NEXT: retq 278 %r = load atomic i128, i128* %p seq_cst, align 16 279 ret i128 %r 280 } 281 282 define i128 @atomic_load_relaxed(i128* %p) { 283 ; CHECK-LABEL: atomic_load_relaxed: 284 ; CHECK: ## %bb.0: 285 ; CHECK-NEXT: pushq %rbx 286 ; CHECK-NEXT: .cfi_def_cfa_offset 16 287 ; CHECK-NEXT: .cfi_offset %rbx, -16 288 ; CHECK-NEXT: xorl %eax, %eax 289 ; CHECK-NEXT: xorl %edx, %edx 290 ; CHECK-NEXT: xorl %ecx, %ecx 291 ; CHECK-NEXT: xorl %ebx, %ebx 292 ; CHECK-NEXT: lock cmpxchg16b (%rdi) 293 ; CHECK-NEXT: popq %rbx 294 ; CHECK-NEXT: retq 295 %r = load atomic i128, i128* %p monotonic, align 16 296 ret i128 %r 297 } 298 299 define void @atomic_store_seq_cst(i128* %p, i128 %in) { 300 ; CHECK-LABEL: atomic_store_seq_cst: 301 ; CHECK: ## %bb.0: 302 ; CHECK-NEXT: pushq %rbx 303 ; CHECK-NEXT: .cfi_def_cfa_offset 16 304 ; CHECK-NEXT: .cfi_offset %rbx, -16 305 ; CHECK-NEXT: movq %rdx, %rcx 306 ; CHECK-NEXT: movq %rsi, %rbx 307 ; CHECK-NEXT: movq (%rdi), %rax 308 ; CHECK-NEXT: movq 8(%rdi), %rdx 309 ; CHECK-NEXT: .p2align 4, 0x90 310 ; CHECK-NEXT: LBB11_1: ## %atomicrmw.start 311 ; CHECK-NEXT: ## =>This Inner Loop Header: Depth=1 312 ; CHECK-NEXT: lock cmpxchg16b (%rdi) 313 ; CHECK-NEXT: jne LBB11_1 314 ; CHECK-NEXT: ## %bb.2: ## %atomicrmw.end 315 ; CHECK-NEXT: popq %rbx 316 ; CHECK-NEXT: retq 317 store atomic i128 %in, i128* %p seq_cst, align 16 318 ret void 319 } 320 321 define void @atomic_store_release(i128* %p, i128 %in) { 322 ; CHECK-LABEL: atomic_store_release: 323 ; CHECK: ## %bb.0: 324 ; CHECK-NEXT: pushq %rbx 325 ; CHECK-NEXT: .cfi_def_cfa_offset 16 326 ; CHECK-NEXT: .cfi_offset %rbx, -16 327 ; CHECK-NEXT: movq %rdx, %rcx 328 ; CHECK-NEXT: movq %rsi, %rbx 329 ; CHECK-NEXT: movq (%rdi), %rax 330 ; CHECK-NEXT: movq 8(%rdi), %rdx 331 ; CHECK-NEXT: .p2align 4, 0x90 332 ; CHECK-NEXT: LBB12_1: ## %atomicrmw.start 333 ; CHECK-NEXT: ## =>This Inner Loop Header: Depth=1 334 ; CHECK-NEXT: lock cmpxchg16b (%rdi) 335 ; CHECK-NEXT: jne LBB12_1 336 ; CHECK-NEXT: ## %bb.2: ## %atomicrmw.end 337 ; CHECK-NEXT: popq %rbx 338 ; CHECK-NEXT: retq 339 store atomic i128 %in, i128* %p release, align 16 340 ret void 341 } 342 343 define void @atomic_store_relaxed(i128* %p, i128 %in) { 344 ; CHECK-LABEL: atomic_store_relaxed: 345 ; CHECK: ## %bb.0: 346 ; CHECK-NEXT: pushq %rbx 347 ; CHECK-NEXT: .cfi_def_cfa_offset 16 348 ; CHECK-NEXT: .cfi_offset %rbx, -16 349 ; CHECK-NEXT: movq %rdx, %rcx 350 ; CHECK-NEXT: movq %rsi, %rbx 351 ; CHECK-NEXT: movq (%rdi), %rax 352 ; CHECK-NEXT: movq 8(%rdi), %rdx 353 ; CHECK-NEXT: .p2align 4, 0x90 354 ; CHECK-NEXT: LBB13_1: ## %atomicrmw.start 355 ; CHECK-NEXT: ## =>This Inner Loop Header: Depth=1 356 ; CHECK-NEXT: lock cmpxchg16b (%rdi) 357 ; CHECK-NEXT: jne LBB13_1 358 ; CHECK-NEXT: ## %bb.2: ## %atomicrmw.end 359 ; CHECK-NEXT: popq %rbx 360 ; CHECK-NEXT: retq 361 store atomic i128 %in, i128* %p unordered, align 16 362 ret void 363 } 364