Home | History | Annotate | Download | only in X86
      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