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

--- Comment #5 from vries at gcc dot gnu.org ---
Created attachment 33610
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33610&action=edit
proof-of-concept patch

Using this proof-of-concept patch, we manage to get the desired code. The patch
uses the fuse-caller-save information in cprop-hardreg, and runs cprop-hardreg
one more time, after pass_fast_rtl_dce.

Obviously it's not desirable to run cprop-hardreg twice. But the pass has
problems with this code:
...
(insn 2 18 3 2 (set (reg/v:SI 1 dx [orig:86 yD.1749 ] [86])
        (reg:SI 5 di [ yD.1749 ])) test.c:9 90 {*movsi_internal}
     (expr_list:REG_DEAD (reg:SI 5 di [ yD.1749 ])
        (nil)))
(note 3 2 6 2 NOTE_INSN_FUNCTION_BEG)
(insn 6 3 7 2 (set (reg:SI 5 di)
        (reg/v:SI 1 dx [orig:86 yD.1749 ] [86])) test.c:10 90 {*movsi_internal}
     (nil))
...

The first time cprop-hardreg runs, it manages to propagate the first copy (insn
2) to the second (insn 6):
...
rescanning insn with uid = 6.
insn 6: replaced reg 1 with 5
...

So insn 6 looks like:
...
(insn 6 3 7 2 (set (reg:SI 5 di)
    (reg:SI 5 di [orig:86 yD.1749 ] [86])) test.c:10 90 {*movsi_internal}
     (nil))
...

That insn is remove by pass_fast_rtl_dce:
...
DCE: Deleting insn 6
deleting insn with uid = 6.
...

And only the second time we run it, we propagate the first copy to the add:
...
insn 9: replaced reg 1 with 5
rescanning insn with uid = 9.
...
which then looks like this:
...
(insn 9 7 15 2 (parallel [
            (set (reg:SI 0 ax [orig:87 D.1767 ] [87])
                (plus:SI (reg:SI 0 ax [orig:83 D.1767 ] [83])
                    (reg:SI 5 di [orig:86 yD.1749 ] [86])))
            (clobber (reg:CC 17 flags))
        ]) test.c:10 220 {*addsi_1}
     (expr_list:REG_DEAD (reg/v:SI 1 dx [orig:86 yD.1749 ] [86])
        (expr_list:REG_UNUSED (reg:CC 17 flags)
            (nil))))
...

That leaves insn 2 dead, which is deleted by dce during sched2:
...
DCE: Deleting insn 2
deleting insn with uid = 2.
...

I'm not sure yet why the cprop-hardreg doesn't work for both cases the first
time, but it's probably that the store to di by insn 6 is registered as a kill
by cprop-hardreg, not taking into account that it's the same value.

Reply via email to