Hi Bill, On Tue, Aug 30, 2016 at 08:23:46PM -0500, Bill Schmidt wrote: > The ada bootstrap failure reported in > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72827 > occurs because of a latent bug in the powerpc back end. The immediate cause > is dead store > elimination removing two stores relative to the frame pointer that are not > dead; however, > DSE is tricked into doing this because we have temporarily adjusted the frame > pointer prior > to performing the loads. DSE relies on the frame pointer remaining constant > to be able to > infer stack stores that are dead.
DSE should really detect this is happening and not do the wrong thing. Maybe add an assert somewhere? Much easier to debug, that way. > Is this ok for trunk, and eventually for backport to the 5 and 6 branches? Will it backport without changes? > Index: gcc/config/rs6000/rs6000.c > =================================================================== > --- gcc/config/rs6000/rs6000.c (revision 239871) > +++ gcc/config/rs6000/rs6000.c (working copy) > @@ -24506,15 +24506,31 @@ rs6000_split_multireg_move (rtx dst, rtx src) > && REG_P (basereg) > && REG_P (offsetreg) > && REGNO (basereg) != REGNO (offsetreg)); > - if (REGNO (basereg) == 0) > + /* We mustn't modify the stack pointer or frame pointer > + as this will confuse dead store elimination. */ > + if ((REGNO (basereg) == STACK_POINTER_REGNUM > + || REGNO (basereg) == HARD_FRAME_POINTER_REGNUM) > + && REGNO (offsetreg) != 0) This should only check for HARD_FRAME_POINTER_REGNUM if there *is* a frame pointer? > { > - rtx tmp = offsetreg; > - offsetreg = basereg; > - basereg = tmp; std::swap (basereg, offsetreg); > + emit_insn (gen_add3_insn (offsetreg, basereg, > + offsetreg)); > + restore_basereg = gen_sub3_insn (offsetreg, offsetreg, > + basereg); > + dst = replace_equiv_address (dst, offsetreg); > } > - emit_insn (gen_add3_insn (basereg, basereg, offsetreg)); > - restore_basereg = gen_sub3_insn (basereg, basereg, offsetreg); > - dst = replace_equiv_address (dst, basereg); > + else > + { > + if (REGNO (basereg) == 0) > + { > + rtx tmp = offsetreg; > + offsetreg = basereg; > + basereg = tmp; > + } > + emit_insn (gen_add3_insn (basereg, basereg, offsetreg)); > + restore_basereg = gen_sub3_insn (basereg, basereg, > + offsetreg); > + dst = replace_equiv_address (dst, basereg); > + } > } > } > else if (GET_CODE (XEXP (dst, 0)) != LO_SUM) If (say) base=r1 offset=r0 this will now adjust r1? That cannot be good. Segher