Atomic instructions require zero-offset memory addresses.
If we allow all addresses, the nonzero-offset addresses will
be prepared in an extra register in an extra instruction before
the actual atomic instruction.

This patch introduces the predicate "riscv_sync_memory_operand",
which restricts the memory operand to be suitable for atomic
instructions.

    gcc/
        PR 100266
        * config/riscv/sync.md (riscv_sync_memory_operand): New.
        * config/riscv/sync.md (riscv_load_reserved): Use new predicate.
        * config/riscv/sync.md (riscv_store_conditional): Likewise.
        * config/riscv/sync.md (atomic_<atomic_optab>): Likewise.
        * config/riscv/sync.md (atomic_fetch_<atomic_optab>): Likewise.
        * config/riscv/sync.md (atomic_exchange): Likewise.
        * config/riscv/sync.md (atomic_compare_and_swap): Likewise.
---
 gcc/config/riscv/sync.md | 34 +++++++++++++++++++---------------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/gcc/config/riscv/sync.md b/gcc/config/riscv/sync.md
index 66548bf891b..8f184d8bbb4 100644
--- a/gcc/config/riscv/sync.md
+++ b/gcc/config/riscv/sync.md
@@ -30,6 +30,10 @@ (define_c_enum "unspec" [
   UNSPEC_STORE_CONDITIONAL
 ])
 
+(define_predicate "riscv_sync_memory_operand"
+  (and (match_operand 0 "memory_operand")
+       (match_code "reg" "0")))
+
 (define_code_iterator any_atomic [plus ior xor and])
 (define_code_attr atomic_optab
   [(plus "add") (ior "or") (xor "xor") (and "and")])
@@ -118,7 +122,7 @@ (define_expand "atomic_store<mode>"
 (define_insn "@riscv_load_reserved<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=r")
     (unspec_volatile:GPR
-      [(match_operand:GPR 1 "memory_operand" "A")
+      [(match_operand:GPR 1 "riscv_sync_memory_operand" "A")
        (match_operand:SI 2 "const_int_operand")]      ;; model
       UNSPEC_LOAD_RESERVED))]
   "TARGET_ATOMIC"
@@ -133,7 +137,7 @@ (define_insn "riscv_load_reserved"
   [(set (match_operand:DI 0 "register_operand" "=r")
     (sign_extend:DI
       (unspec_volatile:SI
-       [(match_operand:SI 1 "memory_operand" "A")
+       [(match_operand:SI 1 "riscv_sync_memory_operand" "A")
         (match_operand:SI 2 "const_int_operand")]      ;; model
        UNSPEC_LOAD_RESERVED)))]
   "TARGET_ATOMIC && TARGET_64BIT"
@@ -143,7 +147,7 @@ (define_insn "riscv_load_reserved"
 (define_insn "@riscv_store_conditional<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=&r")
     (unspec_volatile:GPR [(const_int 0)] UNSPEC_STORE_CONDITIONAL))
-   (set (match_operand:GPR 1 "memory_operand" "=A")
+   (set (match_operand:GPR 1 "riscv_sync_memory_operand" "=A")
     (unspec_volatile:GPR
       [(match_operand:GPR 2 "reg_or_0_operand" "rJ")
        (match_operand:SI 3 "const_int_operand")]      ;; model
@@ -162,7 +166,7 @@ (define_insn "riscv_store_conditional"
   [(set (match_operand:DI 0 "register_operand" "=&r")
     (sign_extend:DI
       (unspec_volatile:SI [(const_int 0)] UNSPEC_STORE_CONDITIONAL)))
-   (set (match_operand:SI 1 "memory_operand" "=A")
+   (set (match_operand:SI 1 "riscv_sync_memory_operand" "=A")
     (unspec_volatile:SI
       [(match_operand:SI 2 "reg_or_0_operand" "rJ")
        (match_operand:SI 3 "const_int_operand")]      ;; model
@@ -172,7 +176,7 @@ (define_insn "riscv_store_conditional"
 )
 
 (define_insn "atomic_<atomic_optab><mode>"
-  [(set (match_operand:GPR 0 "memory_operand" "+A")
+  [(set (match_operand:GPR 0 "riscv_sync_memory_operand" "+A")
        (unspec_volatile:GPR
          [(any_atomic:GPR (match_dup 0)
                     (match_operand:GPR 1 "reg_or_0_operand" "rJ"))
@@ -184,7 +188,7 @@ (define_insn "atomic_<atomic_optab><mode>"
 
 (define_insn "atomic_fetch_<atomic_optab><mode>"
   [(set (match_operand:GPR 0 "register_operand" "=&r")
-       (match_operand:GPR 1 "memory_operand" "+A"))
+       (match_operand:GPR 1 "riscv_sync_memory_operand" "+A"))
    (set (match_dup 1)
        (unspec_volatile:GPR
          [(any_atomic:GPR (match_dup 1)
@@ -198,7 +202,7 @@ (define_insn "atomic_fetch_<atomic_optab><mode>"
 (define_insn "atomic_exchange<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=&r")
        (unspec_volatile:GPR
-         [(match_operand:GPR 1 "memory_operand" "+A")
+         [(match_operand:GPR 1 "riscv_sync_memory_operand" "+A")
           (match_operand:SI 3 "const_int_operand")] ;; model
          UNSPEC_SYNC_EXCHANGE))
    (set (match_dup 1)
@@ -222,14 +226,14 @@ (define_insn "atomic_cas_value_strong<mode>"
   [(set (attr "length") (const_int 20))])
 
 (define_expand "atomic_compare_and_swap<mode>"
-  [(match_operand:SI 0 "register_operand" "")   ;; bool output
-   (match_operand:GPR 1 "register_operand" "")  ;; val output
-   (match_operand:GPR 2 "memory_operand" "")    ;; memory
-   (match_operand:GPR 3 "reg_or_0_operand" "")  ;; expected value
-   (match_operand:GPR 4 "reg_or_0_operand" "")  ;; desired value
-   (match_operand:SI 5 "const_int_operand" "")  ;; is_weak
-   (match_operand:SI 6 "const_int_operand" "")  ;; mod_s
-   (match_operand:SI 7 "const_int_operand" "")] ;; mod_f
+  [(match_operand:SI 0 "register_operand" "")           ;; bool output
+   (match_operand:GPR 1 "register_operand" "")          ;; val output
+   (match_operand:GPR 2 "riscv_sync_memory_operand" "") ;; memory
+   (match_operand:GPR 3 "reg_or_0_operand" "")          ;; expected value
+   (match_operand:GPR 4 "reg_or_0_operand" "")          ;; desired value
+   (match_operand:SI 5 "const_int_operand" "")          ;; is_weak
+   (match_operand:SI 6 "const_int_operand" "")          ;; mod_s
+   (match_operand:SI 7 "const_int_operand" "")]         ;; mod_f
   "TARGET_ATOMIC"
 {
   emit_insn (gen_atomic_cas_value_strong<mode> (operands[1], operands[2],
-- 
2.35.3

Reply via email to