[Bug middle-end/126405] [15/16/17 Regression] Wrong code at -O2 on aarch64

"cvs-commit at gcc dot gnu.org via Gcc-bugs" <[email protected]>
Newsgroups gmane.comp.gcc.bugs
Message-ID <[email protected]/bugzilla/>
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
<[email protected]>:

https://gcc.gnu.org/g:3e5af3a489291ed5adba26132351ae6c59d6d629

commit r16-9425-g3e5af3a489291ed5adba26132351ae6c59d6d629
Author: Kyrylo Tkachov <[email protected]>
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 <[email protected]>
    (cherry picked from commit 6f8fff34e8d854c3f66b2b7c9c64e973a71661cb)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.