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 da8dbf698163..cd9078a40248 100644 --- a/gcc/config/riscv/sync.md +++ b/gcc/config/riscv/sync.md @@ -30,6 +30,10 @@ 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_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 @@ [(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_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 @@ [(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 "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_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_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) @@ -208,14 +212,14 @@ ) (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" { riscv_expand_compare_and_swap (operands); -- 2.31.1