------- Comment #30 from bergner at vnet dot ibm dot com 2006-12-05 04:22 ------- Ok, the problem from comment #28 was due to a latent bug in reload1.c:eliminate_regs_in_insn(). The bug is that eliminate_regs_in_insn() calls single_set() on the passed in insn. This has been fine before, but now with the patch, we end up passing in a parallel insn for a load with update and the load portion of the parallel has the REG_UNUSED flag set. This causes single_set() to return the "update" portion of the parallel instead of returning NULL as it would do normally with parallels. This causes us to only eliminate the update portion of the parallel and we skip eliminating the load portion. The problem insn belfore eliminate_regs_in_insn() looks like:
(insn 12 62 13 2 (parallel [ (set (reg:SI 0 0 [125]) (mem/s/j:SI (plus:SI (reg/f:SI 113 sfp) (const_int 8 [0x8])) [0 S4 A32])) (set (reg/f:SI 9 9 [orig:124 D.965 ] [124]) (plus:SI (reg/f:SI 113 sfp) (const_int 8 [0x8]))) ]) 373 {*movsi_update1} (nil) (expr_list:REG_UNUSED (reg:SI 0 0 [125]) (nil))) After eliminate_regs_in_insn(), we have: (insn 12 62 13 2 (parallel [ (set (reg:SI 0 0 [125]) (mem/s/j:SI (plus:SI (reg/f:SI 113 sfp) (const_int 8 [0x8])) [0 S4 A32])) (set (reg/f:SI 9 9 [orig:124 D.965 ] [124]) (plus:SI (reg/f:SI 1 1) (const_int 8 [0x8]))) ]) 373 {*movsi_update1} (nil) (expr_list:REG_UNUSED (reg:SI 0 0 [125]) (nil))) However, calculate_needs_all_insns() ends up backing out the eliminated (reg/f:SI 1 1) with the non eliminated (reg/f:SI 113 sfp) and (reg/f:SI 113 sfp) never gets eliminated after that and we generate bogus assembler. In addition to the latest patch attached here, I added the following patch to stop eliminate-regs_in_insn from calling single_set for parallel insns. It fixed the bug here and bootstrapped and regtested with no errors. I'll post the combined patch to gcc-patches. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28690