blob: 1abc9dc48c9ae377e4fae53facf46068cc0f52d1 [file] [log] [blame]
Kit Barton7c80f982018-08-28 01:18:29 +00001; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -verify-machineinstrs -ppc-asm-full-reg-names | FileCheck %s --check-prefix=CHECK --check-prefix=PPC32
Robin Morisset22129962014-09-23 20:46:49 +00002; FIXME: -verify-machineinstrs currently fail on ppc64 (mismatched register/instruction).
3; This is already checked for in Atomics-64.ll
Kit Barton7c80f982018-08-28 01:18:29 +00004; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -ppc-asm-full-reg-names | FileCheck %s --check-prefix=CHECK --check-prefix=PPC64
Robin Morisset22129962014-09-23 20:46:49 +00005
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.
12define i8 @load_i8_unordered(i8* %mem) {
13; CHECK-LABEL: load_i8_unordered
Robin Morissete1ca44b2014-10-02 22:27:07 +000014; CHECK: lbz
Robin Morisset22129962014-09-23 20:46:49 +000015; CHECK-NOT: sync
David Blaikiea79ac142015-02-27 21:17:42 +000016 %val = load atomic i8, i8* %mem unordered, align 1
Robin Morisset22129962014-09-23 20:46:49 +000017 ret i8 %val
18}
19define i16 @load_i16_monotonic(i16* %mem) {
20; CHECK-LABEL: load_i16_monotonic
Robin Morissete1ca44b2014-10-02 22:27:07 +000021; CHECK: lhz
Robin Morisset22129962014-09-23 20:46:49 +000022; CHECK-NOT: sync
David Blaikiea79ac142015-02-27 21:17:42 +000023 %val = load atomic i16, i16* %mem monotonic, align 2
Robin Morisset22129962014-09-23 20:46:49 +000024 ret i16 %val
25}
26define i32 @load_i32_acquire(i32* %mem) {
27; CHECK-LABEL: load_i32_acquire
Tim Shen3bef27c2017-05-16 20:18:06 +000028; CHECK: lwz [[VAL:r[0-9]+]]
David Blaikiea79ac142015-02-27 21:17:42 +000029 %val = load atomic i32, i32* %mem acquire, align 4
Tim Shen3bef27c2017-05-16 20:18:06 +000030; CHECK-PPC32: lwsync
31; CHECK-PPC64: cmpw [[CR:cr[0-9]+]], [[VAL]], [[VAL]]
32; CHECK-PPC64: bne- [[CR]], .+4
33; CHECK-PPC64: isync
Robin Morisset22129962014-09-23 20:46:49 +000034 ret i32 %val
35}
36define i64 @load_i64_seq_cst(i64* %mem) {
37; CHECK-LABEL: load_i64_seq_cst
Hal Finkeld86e90a2015-04-23 23:05:08 +000038; CHECK: sync
Robin Morissete1ca44b2014-10-02 22:27:07 +000039; PPC32: __sync_
40; PPC64-NOT: __sync_
Tim Shen3bef27c2017-05-16 20:18:06 +000041; PPC64: ld [[VAL:r[0-9]+]]
David Blaikiea79ac142015-02-27 21:17:42 +000042 %val = load atomic i64, i64* %mem seq_cst, align 8
Tim Shen3bef27c2017-05-16 20:18:06 +000043; CHECK-PPC32: lwsync
44; CHECK-PPC64: cmpw [[CR:cr[0-9]+]], [[VAL]], [[VAL]]
45; CHECK-PPC64: bne- [[CR]], .+4
46; CHECK-PPC64: isync
Robin Morisset22129962014-09-23 20:46:49 +000047 ret i64 %val
48}
49
50; Stores
51define void @store_i8_unordered(i8* %mem) {
52; CHECK-LABEL: store_i8_unordered
53; CHECK-NOT: sync
Robin Morissete1ca44b2014-10-02 22:27:07 +000054; CHECK: stb
Robin Morisset22129962014-09-23 20:46:49 +000055 store atomic i8 42, i8* %mem unordered, align 1
56 ret void
57}
58define void @store_i16_monotonic(i16* %mem) {
59; CHECK-LABEL: store_i16_monotonic
60; CHECK-NOT: sync
Robin Morissete1ca44b2014-10-02 22:27:07 +000061; CHECK: sth
Robin Morisset22129962014-09-23 20:46:49 +000062 store atomic i16 42, i16* %mem monotonic, align 2
63 ret void
64}
65define void @store_i32_release(i32* %mem) {
66; CHECK-LABEL: store_i32_release
Hal Finkel7c5cb062015-04-23 18:30:38 +000067; CHECK: lwsync
Robin Morissete1ca44b2014-10-02 22:27:07 +000068; CHECK: stw
Robin Morisset22129962014-09-23 20:46:49 +000069 store atomic i32 42, i32* %mem release, align 4
70 ret void
71}
72define void @store_i64_seq_cst(i64* %mem) {
73; CHECK-LABEL: store_i64_seq_cst
Hal Finkeld86e90a2015-04-23 23:05:08 +000074; CHECK: sync
Robin Morissete1ca44b2014-10-02 22:27:07 +000075; PPC32: __sync_
76; PPC64-NOT: __sync_
77; PPC64: std
Robin Morisset22129962014-09-23 20:46:49 +000078 store atomic i64 42, i64* %mem seq_cst, align 8
79 ret void
80}
81
82; Atomic CmpXchg
83define i8 @cas_strong_i8_sc_sc(i8* %mem) {
84; CHECK-LABEL: cas_strong_i8_sc_sc
Hal Finkeld86e90a2015-04-23 23:05:08 +000085; CHECK: sync
Robin Morisset22129962014-09-23 20:46:49 +000086 %val = cmpxchg i8* %mem, i8 0, i8 1 seq_cst seq_cst
Hal Finkel7c5cb062015-04-23 18:30:38 +000087; CHECK: lwsync
Robin Morisset22129962014-09-23 20:46:49 +000088 %loaded = extractvalue { i8, i1} %val, 0
89 ret i8 %loaded
90}
91define 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
Hal Finkel7c5cb062015-04-23 18:30:38 +000095; CHECK: lwsync
Robin Morisset22129962014-09-23 20:46:49 +000096 %loaded = extractvalue { i16, i1} %val, 0
97 ret i16 %loaded
98}
99define i32 @cas_strong_i32_acqrel_acquire(i32* %mem) {
100; CHECK-LABEL: cas_strong_i32_acqrel_acquire
Hal Finkel7c5cb062015-04-23 18:30:38 +0000101; CHECK: lwsync
Robin Morisset22129962014-09-23 20:46:49 +0000102 %val = cmpxchg i32* %mem, i32 0, i32 1 acq_rel acquire
Hal Finkel7c5cb062015-04-23 18:30:38 +0000103; CHECK: lwsync
Robin Morisset22129962014-09-23 20:46:49 +0000104 %loaded = extractvalue { i32, i1} %val, 0
105 ret i32 %loaded
106}
107define i64 @cas_weak_i64_release_monotonic(i64* %mem) {
108; CHECK-LABEL: cas_weak_i64_release_monotonic
Hal Finkel7c5cb062015-04-23 18:30:38 +0000109; CHECK: lwsync
Robin Morisset22129962014-09-23 20:46:49 +0000110 %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
117define 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}
123define i16 @xor_i16_seq_cst(i16* %mem, i16 %operand) {
124; CHECK-LABEL: xor_i16_seq_cst
Hal Finkeld86e90a2015-04-23 23:05:08 +0000125; CHECK: sync
Robin Morisset22129962014-09-23 20:46:49 +0000126 %val = atomicrmw xor i16* %mem, i16 %operand seq_cst
Hal Finkel7c5cb062015-04-23 18:30:38 +0000127; CHECK: lwsync
Robin Morisset22129962014-09-23 20:46:49 +0000128 ret i16 %val
129}
130define i32 @xchg_i32_acq_rel(i32* %mem, i32 %operand) {
131; CHECK-LABEL: xchg_i32_acq_rel
Hal Finkel7c5cb062015-04-23 18:30:38 +0000132; CHECK: lwsync
Robin Morisset22129962014-09-23 20:46:49 +0000133 %val = atomicrmw xchg i32* %mem, i32 %operand acq_rel
Hal Finkel7c5cb062015-04-23 18:30:38 +0000134; CHECK: lwsync
Robin Morisset22129962014-09-23 20:46:49 +0000135 ret i32 %val
136}
137define i64 @and_i64_release(i64* %mem, i64 %operand) {
138; CHECK-LABEL: and_i64_release
Hal Finkel7c5cb062015-04-23 18:30:38 +0000139; CHECK: lwsync
Robin Morisset22129962014-09-23 20:46:49 +0000140 %val = atomicrmw and i64* %mem, i64 %operand release
141; CHECK-NOT: [sync ]
142 ret i64 %val
143}