Andrew Geissler | 635e0e4 | 2020-08-21 15:58:33 -0500 | [diff] [blame] | 1 | Upstream-Status: Backport |
| 2 | Signed-off-by: Ross Burton <ross.burton@arm.com> |
| 3 | |
| 4 | From fd2ec4542fd2975e6d3f2f1c1a2639945a84f9e1 Mon Sep 17 00:00:00 2001 |
| 5 | From: Jakub Jelinek <jakub@redhat.com> |
| 6 | Date: Mon, 3 Aug 2020 22:55:28 +0200 |
| 7 | Subject: [PATCH] aarch64: Fix up __aarch64_cas16_acq_rel fallback |
| 8 | |
| 9 | As mentioned in the PR, the fallback path when LSE is unavailable writes |
| 10 | incorrect registers to the memory if the previous content compares equal |
| 11 | to x0, x1 - it writes copy of x0, x1 from the start of function, but it |
| 12 | should write x2, x3. |
| 13 | |
| 14 | 2020-08-03 Jakub Jelinek <jakub@redhat.com> |
| 15 | |
| 16 | PR target/96402 |
| 17 | * config/aarch64/lse.S (__aarch64_cas16_acq_rel): Use x2, x3 instead |
| 18 | of x(tmp0), x(tmp1) in STXP arguments. |
| 19 | |
| 20 | * gcc.target/aarch64/pr96402.c: New test. |
| 21 | |
| 22 | (cherry picked from commit 90b43856fdff7d96d93d22970eca8a86c56e0ddc) |
| 23 | --- |
| 24 | gcc/testsuite/gcc.target/aarch64/pr96402.c | 16 ++++++++++++++++ |
| 25 | libgcc/config/aarch64/lse.S | 2 +- |
| 26 | 2 files changed, 17 insertions(+), 1 deletion(-) |
| 27 | create mode 100644 gcc/testsuite/gcc.target/aarch64/pr96402.c |
| 28 | |
| 29 | diff --git a/gcc/testsuite/gcc.target/aarch64/pr96402.c b/gcc/testsuite/gcc.target/aarch64/pr96402.c |
| 30 | new file mode 100644 |
| 31 | index 00000000000..fa2dddfac15 |
| 32 | --- /dev/null |
| 33 | +++ b/gcc/testsuite/gcc.target/aarch64/pr96402.c |
| 34 | @@ -0,0 +1,16 @@ |
| 35 | +/* PR target/96402 */ |
| 36 | +/* { dg-do run { target int128 } } */ |
| 37 | +/* { dg-options "-moutline-atomics" } */ |
| 38 | + |
| 39 | +int |
| 40 | +main () |
| 41 | +{ |
| 42 | + __int128 a = 0; |
| 43 | + __sync_val_compare_and_swap (&a, (__int128) 0, (__int128) 1); |
| 44 | + if (a != 1) |
| 45 | + __builtin_abort (); |
| 46 | + __sync_val_compare_and_swap (&a, (__int128) 1, (((__int128) 0xdeadbeeffeedbac1ULL) << 64) | 0xabadcafe00c0ffeeULL); |
| 47 | + if (a != ((((__int128) 0xdeadbeeffeedbac1ULL) << 64) | 0xabadcafe00c0ffeeULL)) |
| 48 | + __builtin_abort (); |
| 49 | + return 0; |
| 50 | +} |
| 51 | diff --git a/libgcc/config/aarch64/lse.S b/libgcc/config/aarch64/lse.S |
| 52 | index 64691c601c1..c8fbfbce4fd 100644 |
| 53 | --- a/libgcc/config/aarch64/lse.S |
| 54 | +++ b/libgcc/config/aarch64/lse.S |
| 55 | @@ -203,7 +203,7 @@ STARTFN NAME(cas) |
| 56 | cmp x0, x(tmp0) |
| 57 | ccmp x1, x(tmp1), #0, eq |
| 58 | bne 1f |
| 59 | - STXP w(tmp2), x(tmp0), x(tmp1), [x4] |
| 60 | + STXP w(tmp2), x2, x3, [x4] |
| 61 | cbnz w(tmp2), 0b |
| 62 | 1: ret |
| 63 | |
| 64 | -- |
| 65 | 2.26.2 |
| 66 | |