https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103404

--- Comment #6 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Tamar Christina <tnfch...@gcc.gnu.org>:

https://gcc.gnu.org/g:c2c843849a3392654d1c2191bd9931c0fff1f8ce

commit r12-5801-gc2c843849a3392654d1c2191bd9931c0fff1f8ce
Author: Tamar Christina <tamar.christ...@arm.com>
Date:   Mon Dec 6 10:15:15 2021 +0000

    cse: Make sure duplicate elements are not entered into the equivalence set
[PR103404]

    CSE uses equivalence classes to keep track of expressions that all have the
same
    values at the current point in the program.

    Normal equivalences through SETs only insert and perform lookups in this
set but
    equivalence determined from comparisons, e.g.

    (insn 46 44 47 7 (set (reg:CCZ 17 flags)
            (compare:CCZ (reg:SI 105 [ iD.2893 ])
                (const_int 0 [0]))) "cse.c":18:22 7 {*cmpsi_ccno_1}
         (expr_list:REG_DEAD (reg:SI 105 [ iD.2893 ])
            (nil)))

    creates the equivalence EQ on (reg:SI 105 [ iD.2893 ]) and (const_int 0
[0]).

    This causes a merge to happen between the two equivalence sets denoted by
    (const_int 0 [0]) and (reg:SI 105 [ iD.2893 ]) respectively.

    The operation happens through merge_equiv_classes however this function has
an
    invariant that the classes to be merge not contain any duplicates.  This is
    because it frees entries before merging.

    The given testcase when using the supplied flags trigger an ICE due to the
    equivalence set being

    (rr) p dump_class (class1)
    Equivalence chain for (reg:SI 105 [ iD.2893 ]):
    (reg:SI 105 [ iD.2893 ])
    $3 = void

    (rr) p dump_class (class2)
    Equivalence chain for (const_int 0 [0]):
    (const_int 0 [0])
    (reg:SI 97 [ _10 ])
    (reg:SI 97 [ _10 ])
    $4 = void

    This happens because the original INSN being recorded is

    (insn 18 17 24 2 (set (subreg:V1SI (reg:SI 97 [ _10 ]) 0)
            (const_vector:V1SI [
                    (const_int 0 [0])
                ])) "cse.c":11:9 1363 {*movv1si_internal}
         (expr_list:REG_UNUSED (reg:SI 97 [ _10 ])
            (nil)))

    and we end up generating two equivalences. the first one is simply that
    reg:SI 97 is 0.  The second one is that 0 can be extracted from the V1SI,
so
    subreg (subreg:V1SI (reg:SI 97) 0) 0 == 0.  This nested subreg gets folded
away
    to just reg:SI 97 and we re-insert the same equivalence.

    This patch changes it so that if the nunits of a subreg is 1 then don't
generate
    a vec_select from the subreg as the subreg will be folded away and we get a
dup.

    gcc/ChangeLog:

            PR rtl-optimization/103404
            * cse.c (find_sets_in_insn): Don't select elements out of a V1 mode
            subreg.

    gcc/testsuite/ChangeLog:

            PR rtl-optimization/103404
            * gcc.target/i386/pr103404.c: New test.
  • [Bug rtl-optimization/103404] I... cvs-commit at gcc dot gnu.org via Gcc-bugs

Reply via email to