Home | History | Annotate | Download | only in PowerPC
      1 ; RUN: llc < %s -mtriple=powerpc-apple-darwin -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=PPC32
      2 ; FIXME: -verify-machineinstrs currently fail on ppc64 (mismatched register/instruction).
      3 ; This is already checked for in Atomics-64.ll
      4 ; RUN: llc < %s -mtriple=powerpc64-apple-darwin | FileCheck %s --check-prefix=CHECK --check-prefix=PPC64
      5 
      6 ; FIXME: we don't currently check for the operations themselves with CHECK-NEXT,
      7 ;   because they are implemented in a very messy way with lwarx/stwcx.
      8 ;   It should be fixed soon in another patch.
      9 
     10 ; We first check loads, for all sizes from i8 to i64.
     11 ; We also vary orderings to check for barriers.
     12 define i8 @load_i8_unordered(i8* %mem) {
     13 ; CHECK-LABEL: load_i8_unordered
     14 ; CHECK: lbz
     15 ; CHECK-NOT: sync
     16   %val = load atomic i8, i8* %mem unordered, align 1
     17   ret i8 %val
     18 }
     19 define i16 @load_i16_monotonic(i16* %mem) {
     20 ; CHECK-LABEL: load_i16_monotonic
     21 ; CHECK: lhz
     22 ; CHECK-NOT: sync
     23   %val = load atomic i16, i16* %mem monotonic, align 2
     24   ret i16 %val
     25 }
     26 define i32 @load_i32_acquire(i32* %mem) {
     27 ; CHECK-LABEL: load_i32_acquire
     28 ; CHECK: lwz [[VAL:r[0-9]+]]
     29   %val = load atomic i32, i32* %mem acquire, align 4
     30 ; CHECK-PPC32: lwsync
     31 ; CHECK-PPC64: cmpw [[CR:cr[0-9]+]], [[VAL]], [[VAL]]
     32 ; CHECK-PPC64: bne- [[CR]], .+4
     33 ; CHECK-PPC64: isync
     34   ret i32 %val
     35 }
     36 define i64 @load_i64_seq_cst(i64* %mem) {
     37 ; CHECK-LABEL: load_i64_seq_cst
     38 ; CHECK: sync
     39 ; PPC32: __sync_
     40 ; PPC64-NOT: __sync_
     41 ; PPC64: ld [[VAL:r[0-9]+]]
     42   %val = load atomic i64, i64* %mem seq_cst, align 8
     43 ; CHECK-PPC32: lwsync
     44 ; CHECK-PPC64: cmpw [[CR:cr[0-9]+]], [[VAL]], [[VAL]]
     45 ; CHECK-PPC64: bne- [[CR]], .+4
     46 ; CHECK-PPC64: isync
     47   ret i64 %val
     48 }
     49 
     50 ; Stores
     51 define void @store_i8_unordered(i8* %mem) {
     52 ; CHECK-LABEL: store_i8_unordered
     53 ; CHECK-NOT: sync
     54 ; CHECK: stb
     55   store atomic i8 42, i8* %mem unordered, align 1
     56   ret void
     57 }
     58 define void @store_i16_monotonic(i16* %mem) {
     59 ; CHECK-LABEL: store_i16_monotonic
     60 ; CHECK-NOT: sync
     61 ; CHECK: sth
     62   store atomic i16 42, i16* %mem monotonic, align 2
     63   ret void
     64 }
     65 define void @store_i32_release(i32* %mem) {
     66 ; CHECK-LABEL: store_i32_release
     67 ; CHECK: lwsync
     68 ; CHECK: stw
     69   store atomic i32 42, i32* %mem release, align 4
     70   ret void
     71 }
     72 define void @store_i64_seq_cst(i64* %mem) {
     73 ; CHECK-LABEL: store_i64_seq_cst
     74 ; CHECK: sync
     75 ; PPC32: __sync_
     76 ; PPC64-NOT: __sync_
     77 ; PPC64: std
     78   store atomic i64 42, i64* %mem seq_cst, align 8
     79   ret void
     80 }
     81 
     82 ; Atomic CmpXchg
     83 define i8 @cas_strong_i8_sc_sc(i8* %mem) {
     84 ; CHECK-LABEL: cas_strong_i8_sc_sc
     85 ; CHECK: sync
     86   %val = cmpxchg i8* %mem, i8 0, i8 1 seq_cst seq_cst
     87 ; CHECK: lwsync
     88   %loaded = extractvalue { i8, i1} %val, 0
     89   ret i8 %loaded
     90 }
     91 define i16 @cas_weak_i16_acquire_acquire(i16* %mem) {
     92 ; CHECK-LABEL: cas_weak_i16_acquire_acquire
     93 ;CHECK-NOT: sync
     94   %val = cmpxchg weak i16* %mem, i16 0, i16 1 acquire acquire
     95 ; CHECK: lwsync
     96   %loaded = extractvalue { i16, i1} %val, 0
     97   ret i16 %loaded
     98 }
     99 define i32 @cas_strong_i32_acqrel_acquire(i32* %mem) {
    100 ; CHECK-LABEL: cas_strong_i32_acqrel_acquire
    101 ; CHECK: lwsync
    102   %val = cmpxchg i32* %mem, i32 0, i32 1 acq_rel acquire
    103 ; CHECK: lwsync
    104   %loaded = extractvalue { i32, i1} %val, 0
    105   ret i32 %loaded
    106 }
    107 define i64 @cas_weak_i64_release_monotonic(i64* %mem) {
    108 ; CHECK-LABEL: cas_weak_i64_release_monotonic
    109 ; CHECK: lwsync
    110   %val = cmpxchg weak i64* %mem, i64 0, i64 1 release monotonic
    111 ; CHECK-NOT: [sync ]
    112   %loaded = extractvalue { i64, i1} %val, 0
    113   ret i64 %loaded
    114 }
    115 
    116 ; AtomicRMW
    117 define i8 @add_i8_monotonic(i8* %mem, i8 %operand) {
    118 ; CHECK-LABEL: add_i8_monotonic
    119 ; CHECK-NOT: sync
    120   %val = atomicrmw add i8* %mem, i8 %operand monotonic
    121   ret i8 %val
    122 }
    123 define i16 @xor_i16_seq_cst(i16* %mem, i16 %operand) {
    124 ; CHECK-LABEL: xor_i16_seq_cst
    125 ; CHECK: sync
    126   %val = atomicrmw xor i16* %mem, i16 %operand seq_cst
    127 ; CHECK: lwsync
    128   ret i16 %val
    129 }
    130 define i32 @xchg_i32_acq_rel(i32* %mem, i32 %operand) {
    131 ; CHECK-LABEL: xchg_i32_acq_rel
    132 ; CHECK: lwsync
    133   %val = atomicrmw xchg i32* %mem, i32 %operand acq_rel
    134 ; CHECK: lwsync
    135   ret i32 %val
    136 }
    137 define i64 @and_i64_release(i64* %mem, i64 %operand) {
    138 ; CHECK-LABEL: and_i64_release
    139 ; CHECK: lwsync
    140   %val = atomicrmw and i64* %mem, i64 %operand release
    141 ; CHECK-NOT: [sync ]
    142   ret i64 %val
    143 }
    144