This change brings atomic fences in line with table A.6 of the ISA manual. Relax mem_thread_fence according to the memmodel given.
2023-04-10 Patrick O'Neill <patr...@rivosinc.com> * sync.md (mem_thread_fence_1): Change fence depending on the given memory model. Signed-off-by: Patrick O'Neill <patr...@rivosinc.com> --- v3 Changelog: * Consolidate tests in [PATCH v3 10/10] * Remove helper functions --- gcc/config/riscv/sync.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/gcc/config/riscv/sync.md b/gcc/config/riscv/sync.md index a31b8c4f28a..e91fa29da51 100644 --- a/gcc/config/riscv/sync.md +++ b/gcc/config/riscv/sync.md @@ -42,14 +42,24 @@ DONE; }) -;; Until the RISC-V memory model (hence its mapping from C++) is finalized, -;; conservatively emit a full FENCE. (define_insn "mem_thread_fence_1" [(set (match_operand:BLK 0 "" "") (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER)) (match_operand:SI 1 "const_int_operand" "")] ;; model "" - "fence\tiorw,iorw") + { + enum memmodel model = (enum memmodel) INTVAL (operands[1]); + model = memmodel_base (model); + if (model == MEMMODEL_SEQ_CST) + return "fence\trw,rw"; + else if (model == MEMMODEL_ACQ_REL) + return "fence.tso"; + else if (model == MEMMODEL_ACQUIRE) + return "fence\tr,rw"; + else if (model == MEMMODEL_RELEASE) + return "fence\trw,w"; + } + [(set (attr "length") (const_int 4))]) ;; Atomic memory operations. -- 2.25.1