Home | History | Annotate | Download | only in X86
      1 ; RUN: llc < %s -mtriple=x86_64-apple-macosx10.9 -verify-machineinstrs -mattr=cx16 | FileCheck %s
      2 
      3 @var = global i128 0
      4 
      5 define i128 @val_compare_and_swap(i128* %p, i128 %oldval, i128 %newval) {
      6 ; CHECK-LABEL: val_compare_and_swap:
      7 ; Due to the scheduling right after isel for cmpxchg and given the
      8 ; machine scheduler and copy coalescer do not mess up with physical
      9 ; register live-ranges, we end up with a useless copy.
     10 ;
     11 ; CHECK: movq %rcx, [[TMP:%r[0-9a-z]+]]
     12 ; CHECK: movq %rsi, %rax
     13 ; CHECK: movq %r8, %rcx
     14 ; CHECK: movq [[TMP]], %rbx
     15 ; CHECK: lock
     16 ; CHECK: cmpxchg16b (%rdi)
     17 
     18   %pair = cmpxchg i128* %p, i128 %oldval, i128 %newval acquire acquire
     19   %val = extractvalue { i128, i1 } %pair, 0
     20   ret i128 %val
     21 }
     22 
     23 define void @fetch_and_nand(i128* %p, i128 %bits) {
     24 ; CHECK-LABEL: fetch_and_nand:
     25 ; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
     26 ; CHECK-DAG:     movq (%rdi), %rax
     27 ; CHECK-DAG:     movq 8(%rdi), %rdx
     28 
     29 ; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
     30 ; CHECK:         movq %rdx, %rcx
     31 ; CHECK:         andq [[INCHI]], %rcx
     32 ; CHECK:         movq %rax, %rbx
     33   ; INCLO equivalent comes in in %rsi, so it makes sense it stays there.
     34 ; CHECK:         andq %rsi, %rbx
     35 ; CHECK:         notq %rbx
     36 ; CHECK:         notq %rcx
     37 ; CHECK:         lock
     38 ; CHECK:         cmpxchg16b (%rdi)
     39 ; CHECK:         jne [[LOOP]]
     40 
     41 ; CHECK:         movq %rax, _var
     42 ; CHECK:         movq %rdx, _var+8
     43   %val = atomicrmw nand i128* %p, i128 %bits release
     44   store i128 %val, i128* @var, align 16
     45   ret void
     46 }
     47 
     48 define void @fetch_and_or(i128* %p, i128 %bits) {
     49 ; CHECK-LABEL: fetch_and_or:
     50 ; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
     51 ; CHECK-DAG:     movq (%rdi), %rax
     52 ; CHECK-DAG:     movq 8(%rdi), %rdx
     53 
     54 ; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
     55 ; CHECK:         movq %rax, %rbx
     56   ; INCLO equivalent comes in in %rsi, so it makes sense it stays there.
     57 ; CHECK:         orq %rsi, %rbx
     58 ; CHECK:         movq %rdx, %rcx
     59 ; CHECK:         orq [[INCHI]], %rcx
     60 ; CHECK:         lock
     61 ; CHECK:         cmpxchg16b (%rdi)
     62 ; CHECK:         jne [[LOOP]]
     63 
     64 ; CHECK:         movq %rax, _var
     65 ; CHECK:         movq %rdx, _var+8
     66 
     67   %val = atomicrmw or i128* %p, i128 %bits seq_cst
     68   store i128 %val, i128* @var, align 16
     69   ret void
     70 }
     71 
     72 define void @fetch_and_add(i128* %p, i128 %bits) {
     73 ; CHECK-LABEL: fetch_and_add:
     74 ; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
     75 ; CHECK-DAG:     movq (%rdi), %rax
     76 ; CHECK-DAG:     movq 8(%rdi), %rdx
     77 
     78 ; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
     79 ; CHECK:         movq %rax, %rbx
     80   ; INCLO equivalent comes in in %rsi, so it makes sense it stays there.
     81 ; CHECK:         addq %rsi, %rbx
     82 ; CHECK:         movq %rdx, %rcx
     83 ; CHECK:         adcq [[INCHI]], %rcx
     84 ; CHECK:         lock
     85 ; CHECK:         cmpxchg16b (%rdi)
     86 ; CHECK:         jne [[LOOP]]
     87 
     88 ; CHECK:         movq %rax, _var
     89 ; CHECK:         movq %rdx, _var+8
     90 
     91   %val = atomicrmw add i128* %p, i128 %bits seq_cst
     92   store i128 %val, i128* @var, align 16
     93   ret void
     94 }
     95 
     96 define void @fetch_and_sub(i128* %p, i128 %bits) {
     97 ; CHECK-LABEL: fetch_and_sub:
     98 ; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
     99 ; CHECK-DAG:     movq (%rdi), %rax
    100 ; CHECK-DAG:     movq 8(%rdi), %rdx
    101 
    102 ; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
    103 ; CHECK:         movq %rax, %rbx
    104   ; INCLO equivalent comes in in %rsi, so it makes sense it stays there.
    105 ; CHECK:         subq %rsi, %rbx
    106 ; CHECK:         movq %rdx, %rcx
    107 ; CHECK:         sbbq [[INCHI]], %rcx
    108 ; CHECK:         lock
    109 ; CHECK:         cmpxchg16b (%rdi)
    110 ; CHECK:         jne [[LOOP]]
    111 
    112 ; CHECK:         movq %rax, _var
    113 ; CHECK:         movq %rdx, _var+8
    114 
    115   %val = atomicrmw sub i128* %p, i128 %bits seq_cst
    116   store i128 %val, i128* @var, align 16
    117   ret void
    118 }
    119 
    120 define void @fetch_and_min(i128* %p, i128 %bits) {
    121 ; CHECK-LABEL: fetch_and_min:
    122 ; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
    123 ; CHECK-DAG:     movq (%rdi), %rax
    124 ; CHECK-DAG:     movq 8(%rdi), %rdx
    125 
    126 ; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
    127 ; CHECK:         cmpq
    128 ; CHECK:         sbbq
    129 ; CHECK:         setg
    130 ; CHECK:         cmovneq %rax, %rbx
    131 ; CHECK:         movq [[INCHI]], %rcx
    132 ; CHECK:         cmovneq %rdx, %rcx
    133 ; CHECK:         lock
    134 ; CHECK:         cmpxchg16b (%rdi)
    135 ; CHECK:         jne [[LOOP]]
    136 
    137 ; CHECK:         movq %rax, _var
    138 ; CHECK:         movq %rdx, _var+8
    139 
    140   %val = atomicrmw min i128* %p, i128 %bits seq_cst
    141   store i128 %val, i128* @var, align 16
    142   ret void
    143 }
    144 
    145 define void @fetch_and_max(i128* %p, i128 %bits) {
    146 ; CHECK-LABEL: fetch_and_max:
    147 ; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
    148 ; CHECK-DAG:     movq (%rdi), %rax
    149 ; CHECK-DAG:     movq 8(%rdi), %rdx
    150 
    151 ; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
    152 ; CHECK:         cmpq
    153 ; CHECK:         sbbq
    154 ; CHECK:         setge
    155 ; CHECK:         cmovneq %rax, %rbx
    156 ; CHECK:         movq [[INCHI]], %rcx
    157 ; CHECK:         cmovneq %rdx, %rcx
    158 ; CHECK:         lock
    159 ; CHECK:         cmpxchg16b (%rdi)
    160 ; CHECK:         jne [[LOOP]]
    161 
    162 ; CHECK:         movq %rax, _var
    163 ; CHECK:         movq %rdx, _var+8
    164 
    165   %val = atomicrmw max i128* %p, i128 %bits seq_cst
    166   store i128 %val, i128* @var, align 16
    167   ret void
    168 }
    169 
    170 define void @fetch_and_umin(i128* %p, i128 %bits) {
    171 ; CHECK-LABEL: fetch_and_umin:
    172 ; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
    173 ; CHECK-DAG:     movq (%rdi), %rax
    174 ; CHECK-DAG:     movq 8(%rdi), %rdx
    175 
    176 ; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
    177 ; CHECK:         cmpq
    178 ; CHECK:         sbbq
    179 ; CHECK:         seta
    180 ; CHECK:         cmovneq %rax, %rbx
    181 ; CHECK:         movq [[INCHI]], %rcx
    182 ; CHECK:         cmovneq %rdx, %rcx
    183 ; CHECK:         lock
    184 ; CHECK:         cmpxchg16b (%rdi)
    185 ; CHECK:         jne [[LOOP]]
    186 
    187 ; CHECK:         movq %rax, _var
    188 ; CHECK:         movq %rdx, _var+8
    189 
    190   %val = atomicrmw umin i128* %p, i128 %bits seq_cst
    191   store i128 %val, i128* @var, align 16
    192   ret void
    193 }
    194 
    195 define void @fetch_and_umax(i128* %p, i128 %bits) {
    196 ; CHECK-LABEL: fetch_and_umax:
    197 ; CHECK-DAG:     movq %rdx, [[INCHI:%[a-z0-9]+]]
    198 ; CHECK-DAG:     movq (%rdi), %rax
    199 ; CHECK-DAG:     movq 8(%rdi), %rdx
    200 
    201 ; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
    202 ; CHECK:         cmpq
    203 ; CHECK:         sbbq
    204 ; CHECK:         setb
    205 ; CHECK:         cmovneq %rax, %rbx
    206 ; CHECK:         movq [[INCHI]], %rcx
    207 ; CHECK:         cmovneq %rdx, %rcx
    208 ; CHECK:         lock
    209 ; CHECK:         cmpxchg16b (%rdi)
    210 ; CHECK:         jne [[LOOP]]
    211 
    212 ; CHECK:         movq %rax, _var
    213 ; CHECK:         movq %rdx, _var+8
    214 
    215   %val = atomicrmw umax i128* %p, i128 %bits seq_cst
    216   store i128 %val, i128* @var, align 16
    217   ret void
    218 }
    219 
    220 define i128 @atomic_load_seq_cst(i128* %p) {
    221 ; CHECK-LABEL: atomic_load_seq_cst:
    222 ; CHECK: xorl %eax, %eax
    223 ; CHECK: xorl %edx, %edx
    224 ; CHECK: xorl %ecx, %ecx
    225 ; CHECK: xorl %ebx, %ebx
    226 ; CHECK: lock
    227 ; CHECK: cmpxchg16b (%rdi)
    228 
    229    %r = load atomic i128, i128* %p seq_cst, align 16
    230    ret i128 %r
    231 }
    232 
    233 define i128 @atomic_load_relaxed(i128* %p) {
    234 ; CHECK: atomic_load_relaxed:
    235 ; CHECK: xorl %eax, %eax
    236 ; CHECK: xorl %edx, %edx
    237 ; CHECK: xorl %ecx, %ecx
    238 ; CHECK: xorl %ebx, %ebx
    239 ; CHECK: lock
    240 ; CHECK: cmpxchg16b (%rdi)
    241 
    242    %r = load atomic i128, i128* %p monotonic, align 16
    243    ret i128 %r
    244 }
    245 
    246 define void @atomic_store_seq_cst(i128* %p, i128 %in) {
    247 ; CHECK-LABEL: atomic_store_seq_cst:
    248 ; CHECK:         movq %rdx, %rcx
    249 ; CHECK:         movq %rsi, %rbx
    250 ; CHECK:         movq (%rdi), %rax
    251 ; CHECK:         movq 8(%rdi), %rdx
    252 
    253 ; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
    254 ; CHECK:         lock
    255 ; CHECK:         cmpxchg16b (%rdi)
    256 ; CHECK:         jne [[LOOP]]
    257 ; CHECK-NOT:     callq ___sync_lock_test_and_set_16
    258 
    259    store atomic i128 %in, i128* %p seq_cst, align 16
    260    ret void
    261 }
    262 
    263 define void @atomic_store_release(i128* %p, i128 %in) {
    264 ; CHECK-LABEL: atomic_store_release:
    265 ; CHECK:         movq %rdx, %rcx
    266 ; CHECK:         movq %rsi, %rbx
    267 ; CHECK:         movq (%rdi), %rax
    268 ; CHECK:         movq 8(%rdi), %rdx
    269 
    270 ; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
    271 ; CHECK:         lock
    272 ; CHECK:         cmpxchg16b (%rdi)
    273 ; CHECK:         jne [[LOOP]]
    274 
    275    store atomic i128 %in, i128* %p release, align 16
    276    ret void
    277 }
    278 
    279 define void @atomic_store_relaxed(i128* %p, i128 %in) {
    280 ; CHECK-LABEL: atomic_store_relaxed:
    281 ; CHECK:         movq %rdx, %rcx
    282 ; CHECK:         movq %rsi, %rbx
    283 ; CHECK:         movq (%rdi), %rax
    284 ; CHECK:         movq 8(%rdi), %rdx
    285 
    286 ; CHECK: [[LOOP:.?LBB[0-9]+_[0-9]+]]:
    287 ; CHECK:         lock
    288 ; CHECK:         cmpxchg16b (%rdi)
    289 ; CHECK:         jne [[LOOP]]
    290 
    291    store atomic i128 %in, i128* %p unordered, align 16
    292    ret void
    293 }
    294