blob: 21e3c768ee69e3aac2f41b47560bcbce75e698cb [file] [log] [blame]
Simon Pilgrimfc4d4b22016-07-19 13:35:11 +00001; RUN: llc < %s -mtriple=arm64-linux-gnu -verify-machineinstrs -mcpu=cyclone | FileCheck %s
Tim Northover00ed9962014-03-29 10:18:08 +00002
3@var = global i128 0
4
5define i128 @val_compare_and_swap(i128* %p, i128 %oldval, i128 %newval) {
6; CHECK-LABEL: val_compare_and_swap:
7; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
Tim Northover11a60822014-04-17 20:00:33 +00008; CHECK: ldaxp [[RESULTLO:x[0-9]+]], [[RESULTHI:x[0-9]+]], [x[[ADDR:[0-9]+]]]
9; CHECK-DAG: eor [[MISMATCH_LO:x[0-9]+]], [[RESULTLO]], x2
10; CHECK-DAG: eor [[MISMATCH_HI:x[0-9]+]], [[RESULTHI]], x3
11; CHECK: orr [[MISMATCH:x[0-9]+]], [[MISMATCH_LO]], [[MISMATCH_HI]]
12; CHECK: cbnz [[MISMATCH]], [[DONE:.LBB[0-9]+_[0-9]+]]
13; CHECK: stxp [[SCRATCH_RES:w[0-9]+]], x4, x5, [x[[ADDR]]]
Tim Northover00ed9962014-03-29 10:18:08 +000014; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
Tim Northover11a60822014-04-17 20:00:33 +000015; CHECK: [[DONE]]:
Tim Northover420a2162014-06-13 14:24:07 +000016 %pair = cmpxchg i128* %p, i128 %oldval, i128 %newval acquire acquire
17 %val = extractvalue { i128, i1 } %pair, 0
Tim Northover00ed9962014-03-29 10:18:08 +000018 ret i128 %val
19}
20
21define void @fetch_and_nand(i128* %p, i128 %bits) {
22; CHECK-LABEL: fetch_and_nand:
23; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
24; CHECK: ldxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
Tim Northover55beb642014-07-07 09:06:35 +000025; CHECK-DAG: and [[TMP_REGLO:x[0-9]+]], [[DEST_REGLO]], x2
26; CHECK-DAG: and [[TMP_REGHI:x[0-9]+]], [[DEST_REGHI]], x3
27; CHECK-DAG: mvn [[SCRATCH_REGLO:x[0-9]+]], [[TMP_REGLO]]
28; CHECK-DAG: mvn [[SCRATCH_REGHI:x[0-9]+]], [[TMP_REGHI]]
Tim Northover00ed9962014-03-29 10:18:08 +000029; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
30; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
31
Peter Collingbournea7d936f2018-04-10 16:19:30 +000032; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
Tim Northover00ed9962014-03-29 10:18:08 +000033 %val = atomicrmw nand i128* %p, i128 %bits release
34 store i128 %val, i128* @var, align 16
35 ret void
36}
37
38define void @fetch_and_or(i128* %p, i128 %bits) {
39; CHECK-LABEL: fetch_and_or:
40; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
41; CHECK: ldaxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
Tim Northover11a60822014-04-17 20:00:33 +000042; CHECK-DAG: orr [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2
43; CHECK-DAG: orr [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3
Tim Northover00ed9962014-03-29 10:18:08 +000044; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
45; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
46
Peter Collingbournea7d936f2018-04-10 16:19:30 +000047; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
Tim Northover00ed9962014-03-29 10:18:08 +000048 %val = atomicrmw or i128* %p, i128 %bits seq_cst
49 store i128 %val, i128* @var, align 16
50 ret void
51}
52
53define void @fetch_and_add(i128* %p, i128 %bits) {
54; CHECK-LABEL: fetch_and_add:
55; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
56; CHECK: ldaxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
57; CHECK: adds [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2
Tim Northover11a60822014-04-17 20:00:33 +000058; CHECK: adcs [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3
Tim Northover00ed9962014-03-29 10:18:08 +000059; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
60; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
61
Peter Collingbournea7d936f2018-04-10 16:19:30 +000062; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
Tim Northover00ed9962014-03-29 10:18:08 +000063 %val = atomicrmw add i128* %p, i128 %bits seq_cst
64 store i128 %val, i128* @var, align 16
65 ret void
66}
67
68define void @fetch_and_sub(i128* %p, i128 %bits) {
69; CHECK-LABEL: fetch_and_sub:
70; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
71; CHECK: ldaxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
72; CHECK: subs [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2
Tim Northover11a60822014-04-17 20:00:33 +000073; CHECK: sbcs [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3
Tim Northover00ed9962014-03-29 10:18:08 +000074; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
75; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
76
Peter Collingbournea7d936f2018-04-10 16:19:30 +000077; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
Tim Northover00ed9962014-03-29 10:18:08 +000078 %val = atomicrmw sub i128* %p, i128 %bits seq_cst
79 store i128 %val, i128* @var, align 16
80 ret void
81}
82
83define void @fetch_and_min(i128* %p, i128 %bits) {
84; CHECK-LABEL: fetch_and_min:
85; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
Tim Northover11a60822014-04-17 20:00:33 +000086; CHECK: ldaxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
87; CHECK: cmp [[DEST_REGLO]], x2
Tim Northoveree20caa2014-05-12 18:04:06 +000088; CHECK: cset [[LOCMP:w[0-9]+]], ls
Tim Northover11a60822014-04-17 20:00:33 +000089; CHECK: cmp [[DEST_REGHI:x[0-9]+]], x3
Tim Northoveree20caa2014-05-12 18:04:06 +000090; CHECK: cset [[HICMP:w[0-9]+]], le
Tim Northover11a60822014-04-17 20:00:33 +000091; CHECK: csel [[CMP:w[0-9]+]], [[LOCMP]], [[HICMP]], eq
92; CHECK: cmp [[CMP]], #0
93; CHECK-DAG: csel [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3, ne
94; CHECK-DAG: csel [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2, ne
Tim Northover00ed9962014-03-29 10:18:08 +000095; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
96; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
97
Peter Collingbournea7d936f2018-04-10 16:19:30 +000098; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
Tim Northover00ed9962014-03-29 10:18:08 +000099 %val = atomicrmw min i128* %p, i128 %bits seq_cst
100 store i128 %val, i128* @var, align 16
101 ret void
102}
103
104define void @fetch_and_max(i128* %p, i128 %bits) {
105; CHECK-LABEL: fetch_and_max:
106; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
107; CHECK: ldaxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
Tim Northover11a60822014-04-17 20:00:33 +0000108; CHECK: cmp [[DEST_REGLO]], x2
Tim Northoveree20caa2014-05-12 18:04:06 +0000109; CHECK: cset [[LOCMP:w[0-9]+]], hi
Tim Northover11a60822014-04-17 20:00:33 +0000110; CHECK: cmp [[DEST_REGHI:x[0-9]+]], x3
Tim Northoveree20caa2014-05-12 18:04:06 +0000111; CHECK: cset [[HICMP:w[0-9]+]], gt
Tim Northover11a60822014-04-17 20:00:33 +0000112; CHECK: csel [[CMP:w[0-9]+]], [[LOCMP]], [[HICMP]], eq
113; CHECK: cmp [[CMP]], #0
114; CHECK-DAG: csel [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3, ne
115; CHECK-DAG: csel [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2, ne
Tim Northover00ed9962014-03-29 10:18:08 +0000116; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
117; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
118
Peter Collingbournea7d936f2018-04-10 16:19:30 +0000119; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
Tim Northover00ed9962014-03-29 10:18:08 +0000120 %val = atomicrmw max i128* %p, i128 %bits seq_cst
121 store i128 %val, i128* @var, align 16
122 ret void
123}
124
125define void @fetch_and_umin(i128* %p, i128 %bits) {
126; CHECK-LABEL: fetch_and_umin:
127; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
128; CHECK: ldaxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
Tim Northover11a60822014-04-17 20:00:33 +0000129; CHECK: cmp [[DEST_REGLO]], x2
Tim Northoveree20caa2014-05-12 18:04:06 +0000130; CHECK: cset [[LOCMP:w[0-9]+]], ls
Tim Northover11a60822014-04-17 20:00:33 +0000131; CHECK: cmp [[DEST_REGHI:x[0-9]+]], x3
Tim Northoveree20caa2014-05-12 18:04:06 +0000132; CHECK: cset [[HICMP:w[0-9]+]], ls
Tim Northover11a60822014-04-17 20:00:33 +0000133; CHECK: csel [[CMP:w[0-9]+]], [[LOCMP]], [[HICMP]], eq
134; CHECK: cmp [[CMP]], #0
135; CHECK-DAG: csel [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3, ne
136; CHECK-DAG: csel [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2, ne
Tim Northover00ed9962014-03-29 10:18:08 +0000137; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
138; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
139
Peter Collingbournea7d936f2018-04-10 16:19:30 +0000140; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
Tim Northover00ed9962014-03-29 10:18:08 +0000141 %val = atomicrmw umin i128* %p, i128 %bits seq_cst
142 store i128 %val, i128* @var, align 16
143 ret void
144}
145
146define void @fetch_and_umax(i128* %p, i128 %bits) {
147; CHECK-LABEL: fetch_and_umax:
148; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
149; CHECK: ldaxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
Tim Northover11a60822014-04-17 20:00:33 +0000150; CHECK: cmp [[DEST_REGLO]], x2
Tim Northoveree20caa2014-05-12 18:04:06 +0000151; CHECK: cset [[LOCMP:w[0-9]+]], hi
Tim Northover11a60822014-04-17 20:00:33 +0000152; CHECK: cmp [[DEST_REGHI:x[0-9]+]], x3
Tim Northoveree20caa2014-05-12 18:04:06 +0000153; CHECK: cset [[HICMP:w[0-9]+]], hi
Tim Northover11a60822014-04-17 20:00:33 +0000154; CHECK: csel [[CMP:w[0-9]+]], [[LOCMP]], [[HICMP]], eq
155; CHECK: cmp [[CMP]], #0
156; CHECK-DAG: csel [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3, ne
157; CHECK-DAG: csel [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2, ne
Tim Northover00ed9962014-03-29 10:18:08 +0000158; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
159; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
160
Peter Collingbournea7d936f2018-04-10 16:19:30 +0000161; CHECK-DAG: stp [[DEST_REGLO]], [[DEST_REGHI]]
Tim Northover00ed9962014-03-29 10:18:08 +0000162 %val = atomicrmw umax i128* %p, i128 %bits seq_cst
163 store i128 %val, i128* @var, align 16
164 ret void
165}
166
167define i128 @atomic_load_seq_cst(i128* %p) {
168; CHECK-LABEL: atomic_load_seq_cst:
169; CHECK-NOT: dmb
170; CHECK-LABEL: ldaxp
171; CHECK-NOT: dmb
David Blaikiea79ac142015-02-27 21:17:42 +0000172 %r = load atomic i128, i128* %p seq_cst, align 16
Tim Northover00ed9962014-03-29 10:18:08 +0000173 ret i128 %r
174}
175
Tim Northoverf520eff2015-12-02 18:12:57 +0000176define i128 @atomic_load_relaxed(i64, i64, i128* %p) {
Tim Northover00ed9962014-03-29 10:18:08 +0000177; CHECK-LABEL: atomic_load_relaxed:
178; CHECK-NOT: dmb
Tim Northoverf520eff2015-12-02 18:12:57 +0000179; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
180; CHECK: ldxp [[LO:x[0-9]+]], [[HI:x[0-9]+]], [x2]
181; CHECK-NEXT: stxp [[SUCCESS:w[0-9]+]], [[LO]], [[HI]], [x2]
182; CHECK: cbnz [[SUCCESS]], [[LABEL]]
Tim Northover00ed9962014-03-29 10:18:08 +0000183; CHECK-NOT: dmb
David Blaikiea79ac142015-02-27 21:17:42 +0000184 %r = load atomic i128, i128* %p monotonic, align 16
Tim Northover00ed9962014-03-29 10:18:08 +0000185 ret i128 %r
186}
187
188
189define void @atomic_store_seq_cst(i128 %in, i128* %p) {
190; CHECK-LABEL: atomic_store_seq_cst:
191; CHECK-NOT: dmb
192; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
Tim Northoverb8a1ecf2016-04-13 16:25:39 +0000193; CHECK: ldaxp xzr, [[IGNORED:x[0-9]+]], [x2]
Tim Northover00ed9962014-03-29 10:18:08 +0000194; CHECK: stlxp [[SUCCESS:w[0-9]+]], x0, x1, [x2]
195; CHECK: cbnz [[SUCCESS]], [[LABEL]]
196; CHECK-NOT: dmb
197 store atomic i128 %in, i128* %p seq_cst, align 16
198 ret void
199}
200
201define void @atomic_store_release(i128 %in, i128* %p) {
202; CHECK-LABEL: atomic_store_release:
203; CHECK-NOT: dmb
204; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
Tim Northoverb8a1ecf2016-04-13 16:25:39 +0000205; CHECK: ldxp xzr, [[IGNORED:x[0-9]+]], [x2]
Tim Northover00ed9962014-03-29 10:18:08 +0000206; CHECK: stlxp [[SUCCESS:w[0-9]+]], x0, x1, [x2]
207; CHECK: cbnz [[SUCCESS]], [[LABEL]]
208; CHECK-NOT: dmb
209 store atomic i128 %in, i128* %p release, align 16
210 ret void
211}
212
213define void @atomic_store_relaxed(i128 %in, i128* %p) {
214; CHECK-LABEL: atomic_store_relaxed:
215; CHECK-NOT: dmb
216; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
Tim Northoverb8a1ecf2016-04-13 16:25:39 +0000217; CHECK: ldxp xzr, [[IGNORED:x[0-9]+]], [x2]
Tim Northover00ed9962014-03-29 10:18:08 +0000218; CHECK: stxp [[SUCCESS:w[0-9]+]], x0, x1, [x2]
219; CHECK: cbnz [[SUCCESS]], [[LABEL]]
220; CHECK-NOT: dmb
221 store atomic i128 %in, i128* %p unordered, align 16
222 ret void
223}