On 7/11/2026 12:01 PM, Jin Ma wrote:
RISCV_CALL_ADDRESS_TEMP and RISCV_PROLOGUE_TEMP2 both resolve to x6/t1.
When a weak-symbol indirect sibcall materializes the target address into
t1 and the function has an RVV scalable frame, the epilogue overwrites
t1 with vlenb*N before the final jump.

Fix by constructing SIBCALL_REGS dynamically from JALR_REGS, excluding
fixed and callee-saved GPRs, and additionally t1 under TARGET_VECTOR.
Reject sibcall when no safe target register (t4-t6) is available.

gcc/ChangeLog:

        * config/riscv/riscv.cc (riscv_conditional_register_usage):
        Construct SIBCALL_REGS dynamically; exclude t1 under TARGET_VECTOR.
        (riscv_sibcall_has_safe_target_reg_p): New.
        (riscv_function_ok_for_sibcall): Reject when no safe reg available.

gcc/testsuite/ChangeLog:

        * gcc.target/riscv/rvv/base/sibcall-scalable-frame-weak.c: New.
        * gcc.target/riscv/rvv/base/sibcall-no-safe-reg.c: New.
        * gcc.target/riscv/rvv/base/sibcall-ffixed-t4.c: New.
        * gcc.target/riscv/rvv/base/sibcall-weak-no-vector.c: New.
So don't we potentially need to reinitialize the register file if the arch string is changed via a function attribute or FMV?    I'm having trouble putting my finger precisely on where to fix, but I suspect conditional_register_usage isn't the right place anymore (it was in the past).
@@ -12700,6 +12724,10 @@ riscv_function_ok_for_sibcall (tree decl 
ATTRIBUTE_UNUSED,
    if (riscv_cmodel == CM_LARGE)
      return false;
+ /* Need an epilogue-safe indirect sibcall target register. */
+  if (!riscv_sibcall_has_safe_target_reg_p ())
+    return false;
+
    return true;
  }
I suspect we want to verify we have an indirect call before we reject.  Which will likely mean unmarking one or both of the targets as UNUSED since it'd b used at that point.


diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/sibcall-ffixed-t4.c b/gcc/testsuite/gcc.target/riscv/rvv/base/sibcall-ffixed-t4.c
new file mode 100644
index 00000000000..8a26080c1c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/base/sibcall-ffixed-t4.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fPIC -march=rv64gcv -mabi=lp64d -ffixed-t4" } */
+/* Under TARGET_VECTOR, t1 is excluded from SIBCALL_REGS.  */
+
+extern int callee (int) __attribute__((weak));
+
+int
+caller (int x)
+{
+  return callee (x);
+}
+
+/* { dg-final { scan-assembler-not "jr\tt1" } } */
It's a bit unclear what you're trying to test here.  Why fix t4?

jeff

Reply via email to