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