https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100342
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |liuhongt at gcc dot gnu.org --- Comment #11 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (insn 2741 1965 368 2 (set (reg:DI 42 r14 [orig:2067 u128_0 ] [2067]) (mem/c:DI (plus:DI (reg/f:DI 7 sp) (const_int 56 [0x38])) [9 %sfp+-1032 S8 A64])) "pr100342.c":65:24 66 {*movdi_internal} (nil)) ... (insn 613 612 1970 2 (set (reg:QI 4 si [orig:125 _98 ] [125]) (reg:QI 42 r14 [orig:2067 u128_0 ] [2067])) "pr100342.c":68:15 69 {*movqi_internal} (nil)) ... (insn 2737 1971 615 2 (set (reg:DI 6 bp [orig:2067 u128_0 ] [2067]) (reg:DI 42 r14 [orig:2067 u128_0 ] [2067])) "pr100342.c":68:12 66 {*movdi_internal} (nil)) ... (insn 2829 2749 2855 2 (set (reg:DI 42 r14 [2222]) (const_int -71776119061217281 [0xff00ffffffffffff])) "pr100342.c":68:12 66 {*movdi_internal} (nil)) ... (insn 2275 658 659 2 (set (reg:DI 1 dx [2225]) (reg:DI 4 si [orig:125 _98 ] [125])) "pr100342.c":68:12 66 {*movdi_internal} (nil)) ... (insn 2910 2860 677 2 (set (reg:DI 4 si [2227]) (const_int -1095216660481 [0xffffff00ffffffff])) "pr100342.c":68:12 66 {*movdi_internal} (nil)) ... (insn 2287 2286 710 2 (set (reg:DI 1 dx [orig:131 _104 ] [131]) (reg:DI 6 bp [orig:2067 u128_0 ] [2067])) "pr100342.c":72:5 66 {*movdi_internal} (nil)) (insn 710 2287 2172 2 (set (reg:DI 1 dx [orig:131 _104 ] [131]) (bswap:DI (reg:DI 1 dx [orig:131 _104 ] [131]))) "pr100342.c":72:5 872 {*bswapdi2} (nil)) In copyprop_hardreg_forward_1 at the start of that insn 2737 we have: (gdb) p vd->e[1] $32 = {mode = E_DImode, oldest_regno = 1, next_regno = 4294967295, debug_insn_changes = 0x0} (gdb) p vd->e[4] $33 = {mode = E_QImode, oldest_regno = 42, next_regno = 4294967295, debug_insn_changes = 0x0} (gdb) p vd->e[6] $34 = {mode = E_SImode, oldest_regno = 6, next_regno = 4294967295, debug_insn_changes = 0x0} (gdb) p vd->e[42] $35 = {mode = E_DImode, oldest_regno = 42, next_regno = 4, debug_insn_changes = 0x0} which is I think ok, it says %sil is QImode copy of %r14, all other regs we care about here contain their values. At the end of that we have: (gdb) p vd->e[1] $36 = {mode = E_DImode, oldest_regno = 1, next_regno = 4294967295, debug_insn_changes = 0x0} (gdb) p vd->e[4] $37 = {mode = E_QImode, oldest_regno = 42, next_regno = 6, debug_insn_changes = 0x0} (gdb) p vd->e[6] $38 = {mode = E_DImode, oldest_regno = 42, next_regno = 4294967295, debug_insn_changes = 0x0} (gdb) p vd->e[42] $39 = {mode = E_DImode, oldest_regno = 42, next_regno = 4, debug_insn_changes = 0x0} as well as before the insn 2829. That changes it to: (gdb) p vd->e[1] $51 = {mode = E_DImode, oldest_regno = 1, next_regno = 4294967295, debug_insn_changes = 0x0} (gdb) p vd->e[4] $52 = {mode = E_QImode, oldest_regno = 4, next_regno = 6, debug_insn_changes = 0x0} (gdb) p vd->e[6] $53 = {mode = E_DImode, oldest_regno = 4, next_regno = 4294967295, debug_insn_changes = 0x0} (gdb) p vd->e[42] $54 = {mode = E_DImode, oldest_regno = 42, next_regno = 4294967295, debug_insn_changes = 0x0} Same thing at the start of insn 2275. But after that we have: (gdb) p vd->e[1] $61 = {mode = E_DImode, oldest_regno = 4, next_regno = 4294967295, debug_insn_changes = 0x0} (gdb) p vd->e[4] $62 = {mode = E_QImode, oldest_regno = 4, next_regno = 6, debug_insn_changes = 0x0} (gdb) p vd->e[6] $63 = {mode = E_DImode, oldest_regno = 4, next_regno = 1, debug_insn_changes = 0x0} (gdb) p vd->e[42] $64 = {mode = E_DImode, oldest_regno = 42, next_regno = 4294967295, debug_insn_changes = 0x0} I think this step is what looks wrong, it is true that the movq %rsi, %rdx copied all 64-bits of %rsi, but vd->e[4].mode was just QImode, so I think vd->e[1].mode should be also QImode. That remains until before insn 2910, which changes that to: (gdb) p vd->e[1] $84 = {mode = E_DImode, oldest_regno = 6, next_regno = 4294967295, debug_insn_changes = 0x0} (gdb) p vd->e[4] $85 = {mode = E_DImode, oldest_regno = 4, next_regno = 4294967295, debug_insn_changes = 0x0} (gdb) p vd->e[6] $86 = {mode = E_DImode, oldest_regno = 6, next_regno = 1, debug_insn_changes = 0x0} (gdb) p vd->e[42] $87 = {mode = E_DImode, oldest_regno = 42, next_regno = 4294967295, debug_insn_changes = 0x0} and at that point, the fact that %rdx doesn't contain the same value as %rbp - only %dl is guaranteed to be the same as %bpl - is lost. Then when we look up the oldest value of %rdx on insn 2287 we are told it is %rbp.