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

--- Comment #4 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>:

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

commit r12-7262-gf997eef5654f782bedb985c9285862c4d76b3209
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Wed Feb 16 14:48:30 2022 +0100

    combine: Fix up -fcompare-debug issue in the combiner [PR104544]

    On the following testcase on aarch64-linux, we behave differently
    with -g and -g0.

    The problem is that on:
    (insn 10011 10010 10012 2 (set (reg:CC 66 cc)
            (compare:CC (reg:DI 105)
                (const_int 0 [0]))) "pr104544.c":18:3 407 {cmpdi}
         (expr_list:REG_DEAD (reg:DI 105)
            (nil)))
    (insn 10012 10011 10013 2 (set (reg:SI 109)
            (eq:SI (reg:CC 66 cc)
                (const_int 0 [0]))) "pr104544.c":18:3 444 {aarch64_cstoresi}
         (expr_list:REG_DEAD (reg:CC 66 cc)
            (nil)))
    (insn 10013 10012 10016 2 (set (reg:DI 110)
            (zero_extend:DI (reg:SI 109))) "pr104544.c":18:3 111
{*zero_extendsidi2_aarch64}
         (expr_list:REG_DEAD (reg:SI 109)
            (nil)))
    (insn 10016 10013 10017 2 (parallel [
                (set (reg:CC 66 cc)
                    (compare:CC (const_int 0 [0])
                        (reg:DI 110)))
                (set (reg:DI 111)
                    (neg:DI (reg:DI 110)))
            ]) "pr104544.c":18:3 281 {negdi_carryout}
         (expr_list:REG_DEAD (reg:DI 110)
            (nil)))
    ...
    (debug_insn 6 5 7 2 (var_location:SI y (debug_expr:SI D#5))
"pr104544.c":18:3 -1
         (nil))
    (debug_insn 7 6 10033 2 (debug_marker) "pr104544.c":11:3 -1
         (nil))
    (insn 10033 7 10034 2 (set (reg:DI 117 [ _14 ])
            (ior:DI (reg:DI 111)
                (reg:DI 112))) "pr104544.c":11:6 496 {iordi3}
         (expr_list:REG_DEAD (reg:DI 112)
            (expr_list:REG_DEAD (reg:DI 111)
                (nil))))
    we successfully split 3 insns into two:

    Trying 10011, 10013 -> 10016:
     10011: cc:CC=cmp(r105:DI,0)
          REG_DEAD r105:DI
     10013: r110:DI=cc:CC==0
          REG_DEAD cc:CC
     10016: {cc:CC=cmp(0,r110:DI);r111:DI=-r110:DI;}
          REG_DEAD r110:DI
    Failed to match this instruction:
    (parallel [
            (set (reg:CC 66 cc)
                (compare:CC (reg:DI 105)
                    (const_int 0 [0])))
            (set (reg:DI 111)
                (neg:DI (eq:DI (reg:DI 105)
                        (const_int 0 [0]))))
        ])
    Failed to match this instruction:
    (parallel [
            (set (reg:CC 66 cc)
                (compare:CC (reg:DI 105)
                    (const_int 0 [0])))
            (set (reg:DI 111)
                (neg:DI (eq:DI (reg:DI 105)
                        (const_int 0 [0]))))
        ])
    Successfully matched this instruction:
    (set (reg:DI 111)
        (neg:DI (eq:DI (reg:DI 105)
                (const_int 0 [0]))))
    Successfully matched this instruction:
    (set (reg:CC 66 cc)
        (compare:CC (reg:DI 105)
            (const_int 0 [0])))
    Successfully matched this instruction:
    (set (reg:DI 112)
        (neg:DI (eq:DI (reg:CC 66 cc)
                (const_int 0 [0]))))
    allowing combination of insns 10011, 10013 and 10016
    original costs 4 + 4 + 4 = 16
    replacement costs 4 + 4 = 12
    deferring deletion of insn with uid = 10011.

    but the code that searches forward for insns to update their log
    links (before the change there is a link from insn 10033 to insn 10016
    for pseudo 111) only finds insn 10033 and updates the log link if
    -g isn't enabled, otherwise it stops earlier because there are debug insns
    in between.  So, with -g LOG_LINKS of 10033 isn't updated, points
eventually
    to NOTE_INSN_DELETED and so we do not attempt to combine 10033 with other
    insns, while with -g0 we do.

    The following patch fixes that by instead ignoring debug insns during the
    searching.  We can still check BLOCK_FOR_INSN (insn) on those, because
    if we notice DEBUG_INSN in a following basic block, necessarily there won't
    be any further normal insns in the current block after it.

    2022-02-16  Jakub Jelinek  <ja...@redhat.com>

            PR rtl-optimization/104544
            * combine.cc (try_combine): When looking for insn whose links
            should be updated from i3 to i2, don't stop on debug insns, instead
            skip over them.

            * gcc.dg/pr104544.c: New test.

Reply via email to