[Power] Use AtomicExpandPass for fence insertion, and use lwsync where appropriate
[oota-llvm.git] / test / CodeGen / PowerPC / atomics.ll
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-NOT: sync
15   %val = load atomic i8* %mem unordered, align 1
16   ret i8 %val
17 }
18 define i16 @load_i16_monotonic(i16* %mem) {
19 ; CHECK-LABEL: load_i16_monotonic
20 ; CHECK-NOT: sync
21   %val = load atomic i16* %mem monotonic, align 2
22   ret i16 %val
23 }
24 define i32 @load_i32_acquire(i32* %mem) {
25 ; CHECK-LABEL: load_i32_acquire
26   %val = load atomic i32* %mem acquire, align 4
27 ; CHECK: sync 1
28   ret i32 %val
29 }
30 define i64 @load_i64_seq_cst(i64* %mem) {
31 ; CHECK-LABEL: load_i64_seq_cst
32 ; CHECK: sync 0
33   %val = load atomic i64* %mem seq_cst, align 8
34 ; CHECK: sync 1
35   ret i64 %val
36 }
37
38 ; Stores
39 define void @store_i8_unordered(i8* %mem) {
40 ; CHECK-LABEL: store_i8_unordered
41 ; CHECK-NOT: sync
42   store atomic i8 42, i8* %mem unordered, align 1
43   ret void
44 }
45 define void @store_i16_monotonic(i16* %mem) {
46 ; CHECK-LABEL: store_i16_monotonic
47 ; CHECK-NOT: sync
48   store atomic i16 42, i16* %mem monotonic, align 2
49   ret void
50 }
51 define void @store_i32_release(i32* %mem) {
52 ; CHECK-LABEL: store_i32_release
53 ; CHECK: sync 1
54   store atomic i32 42, i32* %mem release, align 4
55   ret void
56 }
57 define void @store_i64_seq_cst(i64* %mem) {
58 ; CHECK-LABEL: store_i64_seq_cst
59 ; CHECK: sync 0
60   store atomic i64 42, i64* %mem seq_cst, align 8
61   ret void
62 }
63
64 ; Atomic CmpXchg
65 define i8 @cas_strong_i8_sc_sc(i8* %mem) {
66 ; CHECK-LABEL: cas_strong_i8_sc_sc
67 ; CHECK: sync 0
68   %val = cmpxchg i8* %mem, i8 0, i8 1 seq_cst seq_cst
69 ; CHECK: sync 1
70   %loaded = extractvalue { i8, i1} %val, 0
71   ret i8 %loaded
72 }
73 define i16 @cas_weak_i16_acquire_acquire(i16* %mem) {
74 ; CHECK-LABEL: cas_weak_i16_acquire_acquire
75 ;CHECK-NOT: sync
76   %val = cmpxchg weak i16* %mem, i16 0, i16 1 acquire acquire
77 ; CHECK: sync 1
78   %loaded = extractvalue { i16, i1} %val, 0
79   ret i16 %loaded
80 }
81 define i32 @cas_strong_i32_acqrel_acquire(i32* %mem) {
82 ; CHECK-LABEL: cas_strong_i32_acqrel_acquire
83 ; CHECK: sync 1
84   %val = cmpxchg i32* %mem, i32 0, i32 1 acq_rel acquire
85 ; CHECK: sync 1
86   %loaded = extractvalue { i32, i1} %val, 0
87   ret i32 %loaded
88 }
89 define i64 @cas_weak_i64_release_monotonic(i64* %mem) {
90 ; CHECK-LABEL: cas_weak_i64_release_monotonic
91 ; CHECK: sync 1
92   %val = cmpxchg weak i64* %mem, i64 0, i64 1 release monotonic
93 ; CHECK-NOT: [sync ]
94   %loaded = extractvalue { i64, i1} %val, 0
95   ret i64 %loaded
96 }
97
98 ; AtomicRMW
99 define i8 @add_i8_monotonic(i8* %mem, i8 %operand) {
100 ; CHECK-LABEL: add_i8_monotonic
101 ; CHECK-NOT: sync
102   %val = atomicrmw add i8* %mem, i8 %operand monotonic
103   ret i8 %val
104 }
105 define i16 @xor_i16_seq_cst(i16* %mem, i16 %operand) {
106 ; CHECK-LABEL: xor_i16_seq_cst
107 ; CHECK: sync 0
108   %val = atomicrmw xor i16* %mem, i16 %operand seq_cst
109 ; CHECK: sync 1
110   ret i16 %val
111 }
112 define i32 @xchg_i32_acq_rel(i32* %mem, i32 %operand) {
113 ; CHECK-LABEL: xchg_i32_acq_rel
114 ; CHECK: sync 1
115   %val = atomicrmw xchg i32* %mem, i32 %operand acq_rel
116 ; CHECK: sync 1
117   ret i32 %val
118 }
119 define i64 @and_i64_release(i64* %mem, i64 %operand) {
120 ; CHECK-LABEL: and_i64_release
121 ; CHECK: sync 1
122   %val = atomicrmw and i64* %mem, i64 %operand release
123 ; CHECK-NOT: [sync ]
124   ret i64 %val
125 }