]> git.ipfire.org Git - thirdparty/gcc.git/commit
RISC-V: Suppress cross CC sibcall optimization from vector
authorTsukasa OI <research_trasio@irq.a4lg.com>
Tue, 9 Sep 2025 01:51:18 +0000 (01:51 +0000)
committerTsukasa OI <research_trasio@irq.a4lg.com>
Thu, 11 Sep 2025 09:19:08 +0000 (09:19 +0000)
commitebd64a42512e53eb2f0b4169f2d68f3c6c5f23a8
tree149e08d3af4986234e8af88d3c0b4c75412855a7
parente9c2a69fe6fe1a20f8ad7b37ecbb3877cd14c514
RISC-V: Suppress cross CC sibcall optimization from vector

In general, tail call optimization requires that the callee's saved
registers are a superset of the caller's.

The Standard Vector Calling Convention Variant (assembler: .variant_cc)
requires that a function with this calling convention preserves vector
registers v1-v7 and v24-v31 across calls (i.e. callee-saved).  However,
the same set of registers are (function-local) temporary registers
(i.e. caller-saved) on the normal (non-vector) calling convention.

Even if a function with this calling convention variant calls another
function with a non-vector calling convention, those vector registers
are correctly clobbered -- except when the sibling (tail) call
optimization occurs as it violates the general rule mentioned above.

If this happens, following function body:

1.  Save v1-v7 and v24-v31 for clobbering
2.  Call another function with a non-vector calling convention
    (which may destroy v1-v7 and/or v24-v31)
3.  Restore v1-v7 and v24-v31
4.  Return.

may be incorrectly optimized into the following sequence:

1.  Save v1-v7 and v24-v31 for clobbering
2.  Restore v1-v7 and v24-v31 (?!)
3.  Jump to another function with a non-vector calling convention
    (which may destroy v1-v7 and/or v24-v31).

This commit suppresses cross CC sibling call optimization from
the vector calling convention variant.

gcc/ChangeLog:

* config/riscv/riscv.cc (riscv_function_ok_for_sibcall):
Suppress cross calling convention sibcall optimization from
the vector calling convention variant.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/rvv/base/abi-call-variant_cc-sibcall.c: New test.
* gcc.target/riscv/rvv/base/abi-call-variant_cc-sibcall-indirect-1.c: Ditto.
* gcc.target/riscv/rvv/base/abi-call-variant_cc-sibcall-indirect-2.c: Ditto.
gcc/config/riscv/riscv.cc
gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-variant_cc-sibcall-indirect-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-variant_cc-sibcall-indirect-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/riscv/rvv/base/abi-call-variant_cc-sibcall.c [new file with mode: 0644]