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.