[Bug middle-end/126405] [15/16/17 Regression] Wrong code at -O2 on aarch64
cvs-commit at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Jul 29 06:51:25 GMT 2026
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126405
--- Comment #7 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-16 branch has been updated by Kyrylo Tkachov
<ktkachov@gcc.gnu.org>:
https://gcc.gnu.org/g:3e5af3a489291ed5adba26132351ae6c59d6d629
commit r16-9425-g3e5af3a489291ed5adba26132351ae6c59d6d629
Author: Kyrylo Tkachov <ktkachov@nvidia.com>
Date: Sun Jul 26 01:48:55 2026 -0700
out-of-SSA: Use all partition names to find the decl to split [PR126405]
split_overlapping_partition_decls gives every partition but one of a
memory-resident VAR_DECL its own artificial decl, so that distinct stack
slots
do not end up sharing a MEM_EXPR. It takes the variable of a partition
from
that partition's representative. set_rtl attaches the base variable of any
name in a partition to that partition's location, so the variable a
partition
is given need not be the one of its representative.
Here the partition holding the loop-carried versions of an oversized vector
temporary has an anonymous representative:
Partition 1 (_2 - 2 14 16 ) _2 has no base variable, while
14 and 16 are g18_lsm.11_14 and _16
Partition 30 (g18_lsm.11_41 - 41 )
Partition 1 is skipped because SSA_NAME_VAR of _2 is null, so partition 30
believes it is the only partition of g18_lsm.11 and keeps the user decl.
Both
128 byte slots then get MEM_EXPR g18_lsm.11. The load/store pair-fusion
pass
groups accesses by MEM_EXPR base and MEM_OFFSET, so it treated two stores
that
are 144 bytes apart as adjacent and fused them:
before (set (mem:V4SI [sp+240]) (reg v17)) ; g18_lsm.11+96
(set (mem:V4SI [sp+384]) (reg v27)) ; g18_lsm.11+112
after (set (mem:V2x16QI [sp+240])
(unspec [(reg v17) (reg v27)] UNSPEC_STP))
[sp+384] is never written.
Work out the variable each partition will be given and key the keep/split
decision on that, reusing the function set_rtl makes the same choice with,
renamed to expand_leader_merge now.
That function keeps the variable it is given first unless
a later one is DECL_IGNORED_P, and expansion hands set_rtl the
representative
before the other names, so the representative's variable goes in first.
A partition holding names of two variables would otherwise be keyed on the
wrong one.
Bootstrapped and tested on aarch64-none-linux-gnu.
gcc/ChangeLog:
PR middle-end/126405
* cfgexpand.cc (leader_merge): Rename to...
(expand_leader_merge): ...this. Make external.
* cfgexpand.h (expand_leader_merge): Declare.
* tree-outof-ssa.cc: Include cfgexpand.h.
(split_overlapping_partition_decls): Determine the variable of a
partition from all of its names.
gcc/testsuite/ChangeLog:
PR middle-end/126405
* gcc.c-torture/execute/pr126405.c: New test.
* gcc.c-torture/execute/pr126405-2.c: New test.
* gcc.dg/pr126405-1.c: New test.
* gcc.dg/pr126405-2.c: New test.
* gcc.dg/pr126405-3.c: New test.
Signed-off-by: Kyrylo Tkachov <ktkachov@nvidia.com>
(cherry picked from commit 6f8fff34e8d854c3f66b2b7c9c64e973a71661cb)
More information about the Gcc-bugs
mailing list