The current model of the LR and SC INSNs requires a sign-extension to use the generated SImode value for conditional branches, which only operate on XLEN registers. However, the sign-extension is actually not required in both cases, therefore this patch introduces additional INSNs that consume the sign-extension.
Rationale: The sign-extension of the loaded value of a LR.W is specified as sign-extended. Therefore, a sign-extension is not required. The sign-extension of the success value a SC.W is specified as non-zero. As sign-extended non-zero value remains non-zero, therefore the sign-extension is not required. gcc/ PR 100266 * config/riscv/sync.md (riscv_load_reserved): New. * config/riscv/sync.md (riscv_store_conditional): New. --- gcc/config/riscv/sync.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/gcc/config/riscv/sync.md b/gcc/config/riscv/sync.md index edff6520b87e..49b860da8ef0 100644 --- a/gcc/config/riscv/sync.md +++ b/gcc/config/riscv/sync.md @@ -125,6 +125,21 @@ "lr.<amo>%A2 %0, %1" ) +;; This pattern allows to consume a sign-extension of the loaded value. +;; This is legal, because the specification of LR.W defines the loaded +;; value to be sign-extended. + +(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 2 "const_int_operand")] ;; model + UNSPEC_LOAD_RESERVED)))] + "TARGET_ATOMIC && TARGET_64BIT" + "lr.w%A2 %0, %1" +) + (define_insn "@riscv_store_conditional<mode>" [(set (match_operand:GPR 0 "register_operand" "=&r") (unspec_volatile:GPR [(const_int 0)] UNSPEC_STORE_CONDITIONAL)) @@ -137,6 +152,25 @@ "sc.<amo>%A3 %0, %z2, %1" ) +;; This pattern allows to consume a sign-extension of the success +;; value of SC.W, which can then be used for instructions which +;; require values of XLEN-size (e.g. conditional branches). +;; This is legal, because any non-zero value remains non-zero +;; after sign-extension. + +(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") + (unspec_volatile:SI + [(match_operand:SI 2 "reg_or_0_operand" "rJ") + (match_operand:SI 3 "const_int_operand")] ;; model + UNSPEC_STORE_CONDITIONAL))] + "TARGET_ATOMIC && TARGET_64BIT" + "sc.w%A3 %0, %z2, %1" +) + (define_insn "atomic_<atomic_optab><mode>" [(set (match_operand:GPR 0 "memory_operand" "+A") (unspec_volatile:GPR -- 2.31.1