[v4,05/10] RISCV: Strengthen atomic stores
Checks
Commit Message
This change makes atomic stores strictly stronger than table A.6 of the
ISA manual. This mapping makes the overall patchset compatible with
table A.7 as well.
2023-04-14 Patrick O'Neill <patrick@rivosinc.com>
PR target/89835
* sync.md (atomic_store<mode>): Use simple store instruction in
combination with a fence.
* pr89835.c: New test.
Signed-off-by: Patrick O'Neill <patrick@rivosinc.com>
---
v3 Changelog:
* Use a trailing fence for atomic stores to be compatible with Table A.7
---
gcc/config/riscv/sync.md | 20 +++++++++++++++++---
gcc/testsuite/gcc.target/riscv/pr89835.c | 9 +++++++++
2 files changed, 26 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/pr89835.c
@@ -53,7 +53,8 @@
;; Atomic memory operations.
-;; Implement atomic stores with amoswap. Fall back to fences for atomic loads.
+;; Implement atomic stores with conservative fences. Fall back to fences for atomic loads.
+;; This allows us to be compatible with the ISA manual Table A.6 and Table A.7.
(define_insn "atomic_store<mode>"
[(set (match_operand:GPR 0 "memory_operand" "=A")
(unspec_volatile:GPR
@@ -61,9 +62,22 @@
(match_operand:SI 2 "const_int_operand")] ;; model
UNSPEC_ATOMIC_STORE))]
"TARGET_ATOMIC"
- "%F2amoswap.<amo>%A2 zero,%z1,%0"
+ {
+ enum memmodel model = (enum memmodel) INTVAL (operands[2]);
+ model = memmodel_base (model);
+
+ if (model == MEMMODEL_SEQ_CST)
+ return "fence\trw,w\;"
+ "s<amo>\t%z1,%0\;"
+ "fence\trw,rw";
+ if (model == MEMMODEL_RELEASE)
+ return "fence\trw,w\;"
+ "s<amo>\t%z1,%0";
+ else
+ return "s<amo>\t%z1,%0";
+ }
[(set_attr "type" "atomic")
- (set (attr "length") (const_int 8))])
+ (set (attr "length") (const_int 12))])
(define_insn "atomic_<atomic_optab><mode>"
[(set (match_operand:GPR 0 "memory_operand" "+A")
new file mode 100644
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* Verify that relaxed atomic stores use simple store instuctions. */
+/* { dg-final { scan-assembler-not "amoswap" } } */
+
+void
+foo(int bar, int baz)
+{
+ __atomic_store_n(&bar, baz, __ATOMIC_RELAXED);
+}