------- Comment #3 from hubicka at gcc dot gnu dot org 2007-09-16 21:52 ------- What happens in this testcase is (mis)behaviour of invariant code motion. On instruction: (set (mem/c/i:SI (plus:DI (reg/f:DI 113 sfp) (const_int 80 [0x50])) [3 S4 A32]) (fix:SI (reg:DF 135)))
the invariant code is trying to replace the write->load pair, however the truncsfdf2 expander is expanding fix from reg to reg will offload the value to memory again, so we are replacing load by: (insn 44 0 45 (parallel [ (set (mem/c/i:SI (plus:DI (reg/f:DI 113 sfp) (const_int 84 [0x54])) [3 S4 A32]) (fix:SI (reg:DF 135))) (clobber (reg:DI 138)) ]) -1 (nil)) (insn 45 44 46 (set (reg:SI 137) (mem/c/i:SI (plus:DI (reg/f:DI 113 sfp) (const_int 84 [0x54])) [3 S4 A32])) -1 (expr_list:REG_EQUAL (fix:SI (reg:DF 135)) (nil))) (insn 46 45 0 (set (reg:SI 136) (reg:SI 137)) -1 (nil)) This is not very sane transformation at all IMO. Zdenek, perhaps we can disable the transform, when force_operand produces a memory load or some similar lame trick? Anyway, the sharing problem is cured by: Index: loop-invariant.c =================================================================== *** loop-invariant.c (revision 128492) --- loop-invariant.c (working copy) *************** move_invariant_reg (struct loop *loop, u *** 1243,1248 **** --- 1243,1249 ---- if (op != reg) emit_move_insn (reg, op); seq = get_insns (); + unshare_all_rtl_in_chain (seq); end_sequence (); if (!seq_insns_valid_p (seq)) I will commit as obvious if testing passes. Still I would hope we can also avoid loop from doing this transform at all. Honza -- hubicka at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- AssignedTo|unassigned at gcc dot gnu |rakdver at gcc dot gnu dot |dot org |org Status|UNCONFIRMED |ASSIGNED Ever Confirmed|0 |1 Last reconfirmed|0000-00-00 00:00:00 |2007-09-16 21:52:08 date| | http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33348