Message ID | 546A8FA7.7000208@redhat.com |
---|---|
State | New |
Headers | show |
On Mon, Nov 17, 2014 at 4:15 PM, Vladimir Makarov <vmakarov@redhat.com> wrote: > The following patch fixes > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63906 > > LRA rematerialization checks SP offsets at origin and rematerialization > places when trying to rematerialize an insn. But the offsets are not valid > if sp elimination is prohibited (e.g. when alloca is used). Value of > frame_pointer_required is a flag of this. Thanks for the fix, it works and glibc is no longer miscompiled. Thanks, Andrew > > The patch was bootstrapped on aarch64 and committed as rev. 217683. > > 2014-11-17 Vladimir Makarov <vmakarov@redhat.com> > > PR rtl-optimization/63906 > * lra-remat.c (operand_to_remat): Check SP and > frame_pointer_required. > > Index: lra-remat.c > =================================================================== > --- lra-remat.c (revision 217658) > +++ lra-remat.c (working copy) > @@ -399,7 +399,13 @@ operand_to_remat (rtx_insn *insn) > > /* First find a pseudo which can be rematerialized. */ > for (reg = id->regs; reg != NULL; reg = reg->next) > - if (reg->type == OP_OUT && ! reg->subreg_p > + /* True FRAME_POINTER_NEEDED might be because we can not follow > + changing sp offsets, e.g. alloca is used. If the insn contains > + stack pointer in such case, we can not rematerialize it as we > + can not know sp offset at a rematerialization place. */ > + if (reg->regno == STACK_POINTER_REGNUM && frame_pointer_needed) > + return -1; > + else if (reg->type == OP_OUT && ! reg->subreg_p > && find_regno_note (insn, REG_UNUSED, reg->regno) == NULL) > { > /* We permits only one spilled reg. */
Index: lra-remat.c =================================================================== --- lra-remat.c (revision 217658) +++ lra-remat.c (working copy) @@ -399,7 +399,13 @@ operand_to_remat (rtx_insn *insn) /* First find a pseudo which can be rematerialized. */ for (reg = id->regs; reg != NULL; reg = reg->next) - if (reg->type == OP_OUT && ! reg->subreg_p + /* True FRAME_POINTER_NEEDED might be because we can not follow + changing sp offsets, e.g. alloca is used. If the insn contains + stack pointer in such case, we can not rematerialize it as we + can not know sp offset at a rematerialization place. */ + if (reg->regno == STACK_POINTER_REGNUM && frame_pointer_needed) + return -1; + else if (reg->type == OP_OUT && ! reg->subreg_p && find_regno_note (insn, REG_UNUSED, reg->regno) == NULL) { /* We permits only one spilled reg. */