summaryrefslogtreecommitdiff
path: root/test/CodeGen/ARM64
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-04-17 20:00:33 +0000
committerTim Northover <tnorthover@apple.com>2014-04-17 20:00:33 +0000
commit90dd89ed81d3d872fb85d5bb87f28f95d0bf0e50 (patch)
tree1dd056461663cfce0e36d90a24f886417ff4eed2 /test/CodeGen/ARM64
parentfa9a0aa77b3b35f48e2484079ed243792d7741fa (diff)
downloadllvm-90dd89ed81d3d872fb85d5bb87f28f95d0bf0e50.tar.gz
llvm-90dd89ed81d3d872fb85d5bb87f28f95d0bf0e50.tar.bz2
llvm-90dd89ed81d3d872fb85d5bb87f28f95d0bf0e50.tar.xz
ARM64: switch to IR-based atomic operations.
Goodbye code! (Game: spot the bug fixed by the change). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206490 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGen/ARM64')
-rw-r--r--test/CodeGen/ARM64/atomic-128.ll112
-rw-r--r--test/CodeGen/ARM64/atomic.ll28
2 files changed, 74 insertions, 66 deletions
diff --git a/test/CodeGen/ARM64/atomic-128.ll b/test/CodeGen/ARM64/atomic-128.ll
index ba7a2da714..925a4b0abf 100644
--- a/test/CodeGen/ARM64/atomic-128.ll
+++ b/test/CodeGen/ARM64/atomic-128.ll
@@ -5,13 +5,14 @@
define i128 @val_compare_and_swap(i128* %p, i128 %oldval, i128 %newval) {
; CHECK-LABEL: val_compare_and_swap:
; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
-; CHECK: ldaxp [[RESULTLO:x[0-9]+]], [[RESULTHI:x[0-9]+]], [x0]
-; CHECK: cmp [[RESULTLO]], x2
-; CHECK: sbc xzr, [[RESULTHI]], x3
-; CHECK: b.ne [[LABEL2:.?LBB[0-9]+_[0-9]+]]
-; CHECK: stxp [[SCRATCH_RES:w[0-9]+]], x4, x5, [x0]
+; CHECK: ldaxp [[RESULTLO:x[0-9]+]], [[RESULTHI:x[0-9]+]], [x[[ADDR:[0-9]+]]]
+; CHECK-DAG: eor [[MISMATCH_LO:x[0-9]+]], [[RESULTLO]], x2
+; CHECK-DAG: eor [[MISMATCH_HI:x[0-9]+]], [[RESULTHI]], x3
+; CHECK: orr [[MISMATCH:x[0-9]+]], [[MISMATCH_LO]], [[MISMATCH_HI]]
+; CHECK: cbnz [[MISMATCH]], [[DONE:.LBB[0-9]+_[0-9]+]]
+; CHECK: stxp [[SCRATCH_RES:w[0-9]+]], x4, x5, [x[[ADDR]]]
; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
-; CHECK: [[LABEL2]]:
+; CHECK: [[DONE]]:
%val = cmpxchg i128* %p, i128 %oldval, i128 %newval acquire acquire
ret i128 %val
}
@@ -20,13 +21,13 @@ define void @fetch_and_nand(i128* %p, i128 %bits) {
; CHECK-LABEL: fetch_and_nand:
; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
; CHECK: ldxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
-; CHECK: bic [[SCRATCH_REGLO:x[0-9]+]], x2, [[DEST_REGLO]]
-; CHECK: bic [[SCRATCH_REGHI:x[0-9]+]], x3, [[DEST_REGHI]]
+; CHECK-DAG: bic [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2
+; CHECK-DAG: bic [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3
; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
-; CHECK: str [[DEST_REGHI]]
-; CHECK: str [[DEST_REGLO]]
+; CHECK-DAG: str [[DEST_REGHI]]
+; CHECK-DAG: str [[DEST_REGLO]]
%val = atomicrmw nand i128* %p, i128 %bits release
store i128 %val, i128* @var, align 16
ret void
@@ -36,13 +37,13 @@ define void @fetch_and_or(i128* %p, i128 %bits) {
; CHECK-LABEL: fetch_and_or:
; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
; CHECK: ldaxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
-; CHECK: orr [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2
-; CHECK: orr [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3
+; CHECK-DAG: orr [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2
+; CHECK-DAG: orr [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3
; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
-; CHECK: str [[DEST_REGHI]]
-; CHECK: str [[DEST_REGLO]]
+; CHECK-DAG: str [[DEST_REGHI]]
+; CHECK-DAG: str [[DEST_REGLO]]
%val = atomicrmw or i128* %p, i128 %bits seq_cst
store i128 %val, i128* @var, align 16
ret void
@@ -53,12 +54,12 @@ define void @fetch_and_add(i128* %p, i128 %bits) {
; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
; CHECK: ldaxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
; CHECK: adds [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2
-; CHECK: adc [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3
+; CHECK: adcs [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3
; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
-; CHECK: str [[DEST_REGHI]]
-; CHECK: str [[DEST_REGLO]]
+; CHECK-DAG: str [[DEST_REGHI]]
+; CHECK-DAG: str [[DEST_REGLO]]
%val = atomicrmw add i128* %p, i128 %bits seq_cst
store i128 %val, i128* @var, align 16
ret void
@@ -69,12 +70,12 @@ define void @fetch_and_sub(i128* %p, i128 %bits) {
; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
; CHECK: ldaxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
; CHECK: subs [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2
-; CHECK: sbc [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3
+; CHECK: sbcs [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3
; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
-; CHECK: str [[DEST_REGHI]]
-; CHECK: str [[DEST_REGLO]]
+; CHECK-DAG: str [[DEST_REGHI]]
+; CHECK-DAG: str [[DEST_REGLO]]
%val = atomicrmw sub i128* %p, i128 %bits seq_cst
store i128 %val, i128* @var, align 16
ret void
@@ -83,16 +84,20 @@ define void @fetch_and_sub(i128* %p, i128 %bits) {
define void @fetch_and_min(i128* %p, i128 %bits) {
; CHECK-LABEL: fetch_and_min:
; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
-; CHECK: ldaxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
-; CHECK: cmp [[DEST_REGLO]], x2
-; CHECK: sbc xzr, [[DEST_REGHI]], x3
-; CHECK: csel [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2, lt
-; CHECK: csel [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3, lt
+; CHECK: ldaxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
+; CHECK: cmp [[DEST_REGLO]], x2
+; CHECK: csinc [[LOCMP:w[0-9]+]], wzr, wzr, hi
+; CHECK: cmp [[DEST_REGHI:x[0-9]+]], x3
+; CHECK: csinc [[HICMP:w[0-9]+]], wzr, wzr, gt
+; CHECK: csel [[CMP:w[0-9]+]], [[LOCMP]], [[HICMP]], eq
+; CHECK: cmp [[CMP]], #0
+; CHECK-DAG: csel [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3, ne
+; CHECK-DAG: csel [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2, ne
; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
-; CHECK: str [[DEST_REGHI]]
-; CHECK: str [[DEST_REGLO]]
+; CHECK-DAG: str [[DEST_REGHI]]
+; CHECK-DAG: str [[DEST_REGLO]]
%val = atomicrmw min i128* %p, i128 %bits seq_cst
store i128 %val, i128* @var, align 16
ret void
@@ -102,15 +107,19 @@ define void @fetch_and_max(i128* %p, i128 %bits) {
; CHECK-LABEL: fetch_and_max:
; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
; CHECK: ldaxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
-; CHECK: cmp [[DEST_REGLO]], x2
-; CHECK: sbc xzr, [[DEST_REGHI]], x3
-; CHECK: csel [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2, gt
-; CHECK: csel [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3, gt
+; CHECK: cmp [[DEST_REGLO]], x2
+; CHECK: csinc [[LOCMP:w[0-9]+]], wzr, wzr, ls
+; CHECK: cmp [[DEST_REGHI:x[0-9]+]], x3
+; CHECK: csinc [[HICMP:w[0-9]+]], wzr, wzr, le
+; CHECK: csel [[CMP:w[0-9]+]], [[LOCMP]], [[HICMP]], eq
+; CHECK: cmp [[CMP]], #0
+; CHECK-DAG: csel [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3, ne
+; CHECK-DAG: csel [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2, ne
; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
-; CHECK: str [[DEST_REGHI]]
-; CHECK: str [[DEST_REGLO]]
+; CHECK-DAG: str [[DEST_REGHI]]
+; CHECK-DAG: str [[DEST_REGLO]]
%val = atomicrmw max i128* %p, i128 %bits seq_cst
store i128 %val, i128* @var, align 16
ret void
@@ -120,15 +129,19 @@ define void @fetch_and_umin(i128* %p, i128 %bits) {
; CHECK-LABEL: fetch_and_umin:
; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
; CHECK: ldaxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
-; CHECK: cmp [[DEST_REGLO]], x2
-; CHECK: sbc xzr, [[DEST_REGHI]], x3
-; CHECK: csel [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2, cc
-; CHECK: csel [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3, cc
+; CHECK: cmp [[DEST_REGLO]], x2
+; CHECK: csinc [[LOCMP:w[0-9]+]], wzr, wzr, hi
+; CHECK: cmp [[DEST_REGHI:x[0-9]+]], x3
+; CHECK: csinc [[HICMP:w[0-9]+]], wzr, wzr, hi
+; CHECK: csel [[CMP:w[0-9]+]], [[LOCMP]], [[HICMP]], eq
+; CHECK: cmp [[CMP]], #0
+; CHECK-DAG: csel [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3, ne
+; CHECK-DAG: csel [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2, ne
; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
-; CHECK: str [[DEST_REGHI]]
-; CHECK: str [[DEST_REGLO]]
+; CHECK-DAG: str [[DEST_REGHI]]
+; CHECK-DAG: str [[DEST_REGLO]]
%val = atomicrmw umin i128* %p, i128 %bits seq_cst
store i128 %val, i128* @var, align 16
ret void
@@ -138,15 +151,19 @@ define void @fetch_and_umax(i128* %p, i128 %bits) {
; CHECK-LABEL: fetch_and_umax:
; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
; CHECK: ldaxp [[DEST_REGLO:x[0-9]+]], [[DEST_REGHI:x[0-9]+]], [x0]
-; CHECK: cmp [[DEST_REGLO]], x2
-; CHECK: sbc xzr, [[DEST_REGHI]], x3
-; CHECK: csel [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2, hi
-; CHECK: csel [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3, hi
+; CHECK: cmp [[DEST_REGLO]], x2
+; CHECK: csinc [[LOCMP:w[0-9]+]], wzr, wzr, ls
+; CHECK: cmp [[DEST_REGHI:x[0-9]+]], x3
+; CHECK: csinc [[HICMP:w[0-9]+]], wzr, wzr, ls
+; CHECK: csel [[CMP:w[0-9]+]], [[LOCMP]], [[HICMP]], eq
+; CHECK: cmp [[CMP]], #0
+; CHECK-DAG: csel [[SCRATCH_REGHI:x[0-9]+]], [[DEST_REGHI]], x3, ne
+; CHECK-DAG: csel [[SCRATCH_REGLO:x[0-9]+]], [[DEST_REGLO]], x2, ne
; CHECK: stlxp [[SCRATCH_RES:w[0-9]+]], [[SCRATCH_REGLO]], [[SCRATCH_REGHI]], [x0]
; CHECK: cbnz [[SCRATCH_RES]], [[LABEL]]
-; CHECK: str [[DEST_REGHI]]
-; CHECK: str [[DEST_REGLO]]
+; CHECK-DAG: str [[DEST_REGHI]]
+; CHECK-DAG: str [[DEST_REGLO]]
%val = atomicrmw umax i128* %p, i128 %bits seq_cst
store i128 %val, i128* @var, align 16
ret void
@@ -164,12 +181,7 @@ define i128 @atomic_load_seq_cst(i128* %p) {
define i128 @atomic_load_relaxed(i128* %p) {
; CHECK-LABEL: atomic_load_relaxed:
; CHECK-NOT: dmb
-; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
; CHECK: ldxp [[LO:x[0-9]+]], [[HI:x[0-9]+]], [x0]
-; CHECK: orr [[SAMELO:x[0-9]+]], [[LO]], xzr
-; CHECK: orr [[SAMEHI:x[0-9]+]], [[HI]], xzr
-; CHECK: stxp [[SUCCESS:w[0-9]+]], [[SAMELO]], [[SAMEHI]], [x0]
-; CHECK: cbnz [[SUCCESS]], [[LABEL]]
; CHECK-NOT: dmb
%r = load atomic i128* %p monotonic, align 16
ret i128 %r
diff --git a/test/CodeGen/ARM64/atomic.ll b/test/CodeGen/ARM64/atomic.ll
index 13502f474d..e8d957a812 100644
--- a/test/CodeGen/ARM64/atomic.ll
+++ b/test/CodeGen/ARM64/atomic.ll
@@ -3,10 +3,9 @@
define i32 @val_compare_and_swap(i32* %p) {
; CHECK-LABEL: val_compare_and_swap:
; CHECK: orr [[NEWVAL_REG:w[0-9]+]], wzr, #0x4
-; CHECK: orr [[OLDVAL_REG:w[0-9]+]], wzr, #0x7
; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
; CHECK: ldaxr [[RESULT:w[0-9]+]], [x0]
-; CHECK: cmp [[RESULT]], [[OLDVAL_REG]]
+; CHECK: cmp [[RESULT]], #7
; CHECK: b.ne [[LABEL2:.?LBB[0-9]+_[0-9]+]]
; CHECK: stxr [[SCRATCH_REG:w[0-9]+]], [[NEWVAL_REG]], [x0]
; CHECK: cbnz [[SCRATCH_REG]], [[LABEL]]
@@ -18,10 +17,9 @@ define i32 @val_compare_and_swap(i32* %p) {
define i64 @val_compare_and_swap_64(i64* %p) {
; CHECK-LABEL: val_compare_and_swap_64:
; CHECK: orr w[[NEWVAL_REG:[0-9]+]], wzr, #0x4
-; CHECK: orr w[[OLDVAL_REG:[0-9]+]], wzr, #0x7
; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
; CHECK: ldxr [[RESULT:x[0-9]+]], [x0]
-; CHECK: cmp [[RESULT]], x[[OLDVAL_REG]]
+; CHECK: cmp [[RESULT]], #7
; CHECK: b.ne [[LABEL2:.?LBB[0-9]+_[0-9]+]]
; CHECK-NOT: stxr x[[NEWVAL_REG]], x[[NEWVAL_REG]]
; CHECK: stxr [[SCRATCH_REG:w[0-9]+]], x[[NEWVAL_REG]], [x0]
@@ -33,10 +31,9 @@ define i64 @val_compare_and_swap_64(i64* %p) {
define i32 @fetch_and_nand(i32* %p) {
; CHECK-LABEL: fetch_and_nand:
-; CHECK: orr [[OLDVAL_REG:w[0-9]+]], wzr, #0x7
; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
; CHECK: ldxr w[[DEST_REG:[0-9]+]], [x0]
-; CHECK: bic [[SCRATCH2_REG:w[0-9]+]], [[OLDVAL_REG]], w[[DEST_REG]]
+; CHECK: and [[SCRATCH2_REG:w[0-9]+]], w[[DEST_REG]], #0xfffffff8
; CHECK-NOT: stlxr [[SCRATCH2_REG]], [[SCRATCH2_REG]]
; CHECK: stlxr [[SCRATCH_REG:w[0-9]+]], [[SCRATCH2_REG]], [x0]
; CHECK: cbnz [[SCRATCH_REG]], [[LABEL]]
@@ -47,13 +44,13 @@ define i32 @fetch_and_nand(i32* %p) {
define i64 @fetch_and_nand_64(i64* %p) {
; CHECK-LABEL: fetch_and_nand_64:
-; CHECK: orr w[[OLDVAL_REG:[0-9]+]], wzr, #0x7
+; CHECK: mov x[[ADDR:[0-9]+]], x0
; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
-; CHECK: ldaxr [[DEST_REG:x[0-9]+]], [x0]
-; CHECK: bic [[SCRATCH2_REG:x[0-9]+]], x[[OLDVAL_REG]], [[DEST_REG]]
-; CHECK: stlxr [[SCRATCH_REG:w[0-9]+]], [[SCRATCH2_REG]], [x0]
+; CHECK: ldaxr [[DEST_REG:x[0-9]+]], [x[[ADDR]]]
+; CHECK: and [[SCRATCH2_REG:x[0-9]+]], [[DEST_REG]], #0xfffffffffffffff8
+; CHECK: stlxr [[SCRATCH_REG:w[0-9]+]], [[SCRATCH2_REG]], [x[[ADDR]]]
; CHECK: cbnz [[SCRATCH_REG]], [[LABEL]]
-; CHECK: mov x0, [[DEST_REG]]
+
%val = atomicrmw nand i64* %p, i64 7 acq_rel
ret i64 %val
}
@@ -74,13 +71,12 @@ define i32 @fetch_and_or(i32* %p) {
define i64 @fetch_and_or_64(i64* %p) {
; CHECK: fetch_and_or_64:
-; CHECK: orr w[[OLDVAL_REG:[0-9]+]], wzr, #0x7
+; CHECK: mov x[[ADDR:[0-9]+]], x0
; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]:
-; CHECK: ldxr [[DEST_REG:x[0-9]+]], [x0]
-; CHECK: orr [[SCRATCH2_REG:x[0-9]+]], [[DEST_REG]], x[[OLDVAL_REG]]
-; CHECK: stxr [[SCRATCH_REG:w[0-9]+]], [[SCRATCH2_REG]], [x0]
+; CHECK: ldxr [[DEST_REG:x[0-9]+]], [x[[ADDR]]]
+; CHECK: orr [[SCRATCH2_REG:x[0-9]+]], [[DEST_REG]], #0x7
+; CHECK: stxr [[SCRATCH_REG:w[0-9]+]], [[SCRATCH2_REG]], [x[[ADDR]]]
; CHECK: cbnz [[SCRATCH_REG]], [[LABEL]]
-; CHECK: mov x0, [[DEST_REG]]
%val = atomicrmw or i64* %p, i64 7 monotonic
ret i64 %val
}