[Bug rtl-optimization/123786] [16 Regression] AArch64: Miscompile at -O3 -mtune=generic-armv9-a since r16-3628-g41b0c7a674e870
cvs-commit at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Tue Mar 3 08:55:56 GMT 2026
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123786
--- Comment #15 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Richard Sandiford <rsandifo@gcc.gnu.org>:
https://gcc.gnu.org/g:0399019276a0e26e5e06cd13296d724bb7afa87b
commit r16-7861-g0399019276a0e26e5e06cd13296d724bb7afa87b
Author: Richard Sandiford <rdsandiford@googlemail.com>
Date: Tue Mar 3 08:55:38 2026 +0000
rtl-ssa: Ensure live-out uses before redefinitions [PR123786]
This patch fixes cases in which:
(1) a register is live in to an EBB;
(2) the register is live out of at least one BB in the EBB; and
(3) the register is redefined by a later BB in the same EBB.
We were supposed to create live-out uses for (2), so that the redefinition
in (3) cannot be moved up into the live range of (1).
The patch does this by collecting all definitions in second and
subsequence BBs of an EBB. It then creates degenerate phis for those
registers that do not naturally need phis. For speed and simplicity,
the patch does not check for (2). If a register is live in to the EBB,
then it must be used somewhere, either in the EBB itself or in a
successor outside of the EBB. A degenerate phi would eventually
be needed in either case.
This requires moving append_bb earlier, so that add_phi_nodes can
iterate over the BBs in an EBB.
live_out_value contained an on-the-fly optimisation to remove redundant
phis. That was a mistake. live_out_value can be called multiple times
for the same quantity. Replacing a phi on-the-fly messes up bookkeeping
for second and subsequent calls.
The live_out_value optimisation was mostly geared towards memory.
As an experiment, I added an assert for when the optimisation applied
to registers. It only fired once in an x86_64-linux-gnu bootstrap &
regression test, in gcc.dg/tree-prof/split-1.c. That's a very poor
(but unsurprising) return. And the optimisation will still be done
eventually anyway, during the phi simplification phase. Doing it on
the fly was just supposed to allow the phi's memory to be reused.
The patch therefore moves the optimisation into add_phi_nodes and
restricts it to memory (for which it does make a difference).
gcc/
PR rtl-optimization/123786
* rtl-ssa/functions.h (function_info::live_out_value): Delete.
(function_info::create_degenerate_phi): New overload.
* rtl-ssa/blocks.cc (all_uses_are_live_out_uses): Delete.
(function_info::live_out_value): Likewise.
(function_info::replace_phi): Keep live-out uses if they are
followed
by a definition in the same EBB.
(function_info::create_degenerate_phi): New overload, extracted
from create_reg_use.
(function_info::add_phi_nodes): Ensure that there is a phi for
every live input that is redefined by a second or subsequent
block in the EBB. Record that such phis need live-out uses.
(function_info::record_block_live_out): Use
look_through_degenerate_phi
rather than live_out_value when setting phi inputs. Remove use of
live_out_value for live-out uses. Inline the old handling of
bb_mem_live_out.
(function_info::start_block): Move append_bb call to...
(function_info::create_ebbs): ...here.
* rtl-ssa/insns.cc (function_info::create_reg_use): Use the new
create_degenerate_phi overload.
gcc/testsuite/
PR rtl-optimization/123786
* gcc.target/aarch64/pr123786.c: New test.
Co-authored-by: Artemiy Volkov <artemiy.volkov@arm.com>
More information about the Gcc-bugs
mailing list