RISC-V: Prevent popretz optimization from crossing function calls.
Fixes RISC-V optimization that incorrectly deleted code across function calls.
A RISC-V optimization pass, combine_popretz, incorrectly deleted a li a0, 0 instruction when it occurred across a function call. This instruction was intended to set up the first argument for the called function or to clear register a0 before a return. The pass’s backward scan failed to stop at calls, mistaking argument setup for dead code. This commit corrects the scan to respect function call boundaries, preventing incorrect instruction deletion and ensuring correct argument passing and return values.
In Details
The pass_combine_popretz::execute pass on RISC-V incorrectly deleted li a0, 0 instructions that were inputs to cm.popret by scanning backwards. The scan did not stop at CALL_INSNs. Arguments to calls are in CALL_INSN_FUNCTION_USAGE, and reg_referenced_p does not examine these. Also, a SET instruction within a PARALLEL, which could hide the li a0, 0 setting up a call argument, was not matched by the simple SET test. This resulted in cm.popretz misinterpreting cm.popret, leading to incorrect values in a0 for callees and incorrect return values…
- RISC-V
- An open-standard instruction set architecture (ISA) based on Reduced Instruction Set Computing principles.
- popretz
- A RISC-V specific optimization pass that likely aims to optimize return instructions, possibly by combining them with preceding operations.
- li a0, 0
- An assembly instruction that loads the immediate value 0 into register a0. Register a0 is often used for the first argument in function calls or for return values.
- CALL_INSN_FUNCTION_USAGE
- An internal GCC data structure associated with call instructions, used to track function call arguments and return values.
- reg_referenced_p
- A GCC internal function to check if a register is referenced (used) within a certain code segment.