1 ; RUN: llc < %s -mtriple=powerpc-apple-darwin -march=ppc32 -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=powerpc-apple-darwin -march=ppc64 | 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 29 %val = load atomic i32, i32* %mem acquire, align 4 30 ; CHECK: lwsync 31 ret i32 %val 32 } 33 define i64 @load_i64_seq_cst(i64* %mem) { 34 ; CHECK-LABEL: load_i64_seq_cst 35 ; CHECK: sync 36 ; PPC32: __sync_ 37 ; PPC64-NOT: __sync_ 38 ; PPC64: ld 39 %val = load atomic i64, i64* %mem seq_cst, align 8 40 ; CHECK: lwsync 41 ret i64 %val 42 } 43 44 ; Stores 45 define void @store_i8_unordered(i8* %mem) { 46 ; CHECK-LABEL: store_i8_unordered 47 ; CHECK-NOT: sync 48 ; CHECK: stb 49 store atomic i8 42, i8* %mem unordered, align 1 50 ret void 51 } 52 define void @store_i16_monotonic(i16* %mem) { 53 ; CHECK-LABEL: store_i16_monotonic 54 ; CHECK-NOT: sync 55 ; CHECK: sth 56 store atomic i16 42, i16* %mem monotonic, align 2 57 ret void 58 } 59 define void @store_i32_release(i32* %mem) { 60 ; CHECK-LABEL: store_i32_release 61 ; CHECK: lwsync 62 ; CHECK: stw 63 store atomic i32 42, i32* %mem release, align 4 64 ret void 65 } 66 define void @store_i64_seq_cst(i64* %mem) { 67 ; CHECK-LABEL: store_i64_seq_cst 68 ; CHECK: sync 69 ; PPC32: __sync_ 70 ; PPC64-NOT: __sync_ 71 ; PPC64: std 72 store atomic i64 42, i64* %mem seq_cst, align 8 73 ret void 74 } 75 76 ; Atomic CmpXchg 77 define i8 @cas_strong_i8_sc_sc(i8* %mem) { 78 ; CHECK-LABEL: cas_strong_i8_sc_sc 79 ; CHECK: sync 80 %val = cmpxchg i8* %mem, i8 0, i8 1 seq_cst seq_cst 81 ; CHECK: lwsync 82 %loaded = extractvalue { i8, i1} %val, 0 83 ret i8 %loaded 84 } 85 define i16 @cas_weak_i16_acquire_acquire(i16* %mem) { 86 ; CHECK-LABEL: cas_weak_i16_acquire_acquire 87 ;CHECK-NOT: sync 88 %val = cmpxchg weak i16* %mem, i16 0, i16 1 acquire acquire 89 ; CHECK: lwsync 90 %loaded = extractvalue { i16, i1} %val, 0 91 ret i16 %loaded 92 } 93 define i32 @cas_strong_i32_acqrel_acquire(i32* %mem) { 94 ; CHECK-LABEL: cas_strong_i32_acqrel_acquire 95 ; CHECK: lwsync 96 %val = cmpxchg i32* %mem, i32 0, i32 1 acq_rel acquire 97 ; CHECK: lwsync 98 %loaded = extractvalue { i32, i1} %val, 0 99 ret i32 %loaded 100 } 101 define i64 @cas_weak_i64_release_monotonic(i64* %mem) { 102 ; CHECK-LABEL: cas_weak_i64_release_monotonic 103 ; CHECK: lwsync 104 %val = cmpxchg weak i64* %mem, i64 0, i64 1 release monotonic 105 ; CHECK-NOT: [sync ] 106 %loaded = extractvalue { i64, i1} %val, 0 107 ret i64 %loaded 108 } 109 110 ; AtomicRMW 111 define i8 @add_i8_monotonic(i8* %mem, i8 %operand) { 112 ; CHECK-LABEL: add_i8_monotonic 113 ; CHECK-NOT: sync 114 %val = atomicrmw add i8* %mem, i8 %operand monotonic 115 ret i8 %val 116 } 117 define i16 @xor_i16_seq_cst(i16* %mem, i16 %operand) { 118 ; CHECK-LABEL: xor_i16_seq_cst 119 ; CHECK: sync 120 %val = atomicrmw xor i16* %mem, i16 %operand seq_cst 121 ; CHECK: lwsync 122 ret i16 %val 123 } 124 define i32 @xchg_i32_acq_rel(i32* %mem, i32 %operand) { 125 ; CHECK-LABEL: xchg_i32_acq_rel 126 ; CHECK: lwsync 127 %val = atomicrmw xchg i32* %mem, i32 %operand acq_rel 128 ; CHECK: lwsync 129 ret i32 %val 130 } 131 define i64 @and_i64_release(i64* %mem, i64 %operand) { 132 ; CHECK-LABEL: and_i64_release 133 ; CHECK: lwsync 134 %val = atomicrmw and i64* %mem, i64 %operand release 135 ; CHECK-NOT: [sync ] 136 ret i64 %val 137 } 138