Rescan sibling calls after inserting call-used register zeroing
Fixes compiler crash when zeroing call-used registers affects sibling call clobber information.
This commit addresses a compiler crash (ICE) in the dataflow analysis pass when zeroing call-used registers on return paths that also contain sibling calls. The issue arose because zeroing registers updated the exit block’s use set, invalidating previously recorded clobber information for sibling calls. The fix ensures a rescan of call-related dataflow information after register zeroing, preventing the ICE.
In Details
The gen_call_used_regs_seq pass updates crtl->must_be_zero_on_return. This modification is reflected in df_epilogue_uses_p and consequently the exit block's use set. df_get_call_refs uses this set to determine sibling call clobbers. If the set grows due to register zeroing, prior clobber information becomes stale, leading to an ICE in passes like narrow_gp_writes when df_refs_verify encounters inconsistencies. The fix involves calling df_update_entry_exit_and_calls after all return blocks are processed, similar to solutions for PR78400 and PR100.
- ICE
- Internal Compiler Error, a crash within the compiler itself, usually indicating a bug in the compiler's logic.
- call-used registers
- Registers that a called function is permitted to modify (clobber).
- sibling call
- A type of indirect function call where the callee is also a return instruction, effectively making the call a tail call that does not return to the caller of the current function.
- dataflow analysis
- A static code analysis technique used by compilers to gather information about the possible values of variables at different points in a program.
- RTL
- Register Transfer Language, an intermediate representation used by GCC between the compiler's front-end and the back-end machine-specific code generation.
- aarch64
- The 64-bit ARM architecture, commonly used in mobile devices and servers.