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

            Bug ID: 119841
           Summary: [15 Regression] gcc.target/cris/pr93372-2.c
           Product: gcc
           Version: 14.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: hp at gcc dot gnu.org
                CC: rsandifo at gcc dot gnu.org
  Target Milestone: ---
            Target: cris-elf

>From r15-9239-g4d7a634f6d4102 "combine: Allow 2->2 combinations,
but with a tweak [PR116398]", there's a regression for cris-elf:

Running /x/gcc/gcc/testsuite/gcc.target/cris/cris.exp ...
FAIL: gcc.target/cris/pr93372-2.c scan-assembler-not \tcmp|\ttest
FAIL: gcc.target/cris/pr93372-2.c scan-assembler-times \tmove 1

The testcase checks for elimination of redundant compare insns, from
e.g. the cmpelim pass.  Where gcc used to emit:
_f:
        sub.d $r11,$r10
        seq $r9
        move.d $r9,[$r12]
        ret
        sge $r10

it now emits:

_f:
        move.d $r10,$r9
        sub.d $r11,$r9
        cmp.d $r11,$r10
        seq $r10
        move.d $r10,[$r12]
        cmpq 0,$r9
        ret
        sge $r10

So, not only is there an extra move, but also none of the compares are
eliminated.  It's all due to the combine.  Where it used to back off,
it helpfully "optimizes" these two insns (compact format):

     8: {r30:SI=r32:SI-r33:SI;clobber ccr:CC;}
     9: {r36:SI=r30:SI==0;clobber ccr:CC;}
into:
     8: {r30:SI=r40:SI-r41:SI;clobber ccr:CC;}
     9: {r36:SI=r40:SI==r41:SI;clobber ccr:CC;}

i.e. (in classic format) from
 (eq:SI (reg/v:SI 30 [ c ]) (const_int 0 [0]))
to
 (eq:SI (reg:SI 40 [ a ]) (reg:SI 41 [ b ]))
in insn 9.

The costs are (currently) the same.

Because the costs (hence also the total cost) are the same, that
change may look benevolent to you.

What is not seen in the compact format is that this extends the
lifetime of two registers that died in insn 8.  Zombie apocalypse
ensues.  Or at least pressure on the living: register 30 is born and
must stay alive while at the same time both register 40 and 41 are
still alive, where previously they were killed and either could be
mapped to the same hard register as register 30.

The consequences is for the test-case, one extra move insn and the rtl
no longer matching what cmpelim looks for, so the compares aren't
eliminated.

For reference use the classic, detailed format.  Incoming to combine:

(gdb) p i2
$127 = (rtx_insn *) 0x7ffff7a94380
(gdb) pr
(insn 8 5 9 2 (parallel [
            (set (reg/v:SI 30 [ c ])
                (minus:SI (reg:SI 40 [ a ])
                    (reg:SI 41 [ b ])))
            (clobber (reg:CC 19 ccr))
        ])
"/mnt/storage0/hp/tmpdir/250407_9238/gcc/gcc/testsuite/gcc.target/cris/pr93372-2.c":12:7
76 {*subsi3}
     (expr_list:REG_DEAD (reg:SI 41 [ b ])
        (expr_list:REG_UNUSED (reg:CC 19 ccr)
            (expr_list:REG_DEAD (reg:SI 40 [ a ])
                (nil)))))
(gdb) p i3
$128 = (rtx_insn *) 0x7ffff7a943c0
(gdb) pr
(insn 9 8 10 2 (parallel [
            (set (reg:SI 36 [ _1 ])
                (eq:SI (reg/v:SI 30 [ c ])
                    (const_int 0 [0])))
            (clobber (reg:CC 19 ccr))
        ])
"/mnt/storage0/hp/tmpdir/250407_9238/gcc/gcc/testsuite/gcc.target/cris/pr93372-2.c":15:11
355 {*cstoresieq4}
     (expr_list:REG_UNUSED (reg:CC 19 ccr)
        (nil)))

On the way out from try_combine:

(gdb) p i2
$91 = (rtx_insn *) 0x7ffff7a94380
(gdb) pr
(insn 8 5 9 2 (parallel [
            (set (reg/v:SI 30 [ c ])
                (minus:SI (reg:SI 40 [ a ])
                    (reg:SI 41 [ b ])))
            (clobber (reg:CC 19 ccr))
        ])
"/mnt/storage0/hp/tmpdir/250407_9239/gcc/gcc/testsuite/gcc.target/cris/pr93372-2.c":12:7
76 {*subsi3}
     (expr_list:REG_UNUSED (reg:CC 19 ccr)
        (nil)))
(gdb) p i3
$92 = (rtx_insn *) 0x7ffff7a943c0
(gdb) pr
(insn 9 8 10 2 (parallel [
            (set (reg:SI 36 [ _1 ])
                (eq:SI (reg:SI 40 [ a ])
                    (reg:SI 41 [ b ])))
            (clobber (reg:CC 19 ccr))
        ])
"/mnt/storage0/hp/tmpdir/250407_9239/gcc/gcc/testsuite/gcc.target/cris/pr93372-2.c":15:11
355 {*cstoresieq4}
     (expr_list:REG_DEAD (reg:SI 40 [ a ])
        (expr_list:REG_DEAD (reg:SI 41 [ b ])
            (expr_list:REG_UNUSED (reg:CC 19 ccr)
                (nil)))))

This has two (including) solutions: hack the target so that the cost of a
comparison operator where the second operant isn't const0_rtx is higher, or fix
combine so it breaks ties considering the higher register pressure.
(I'm pursuing both.)

Reply via email to