On Thu, 27 Apr 2017, Jakub Jelinek wrote: > Hi! > > As the patch I've just posted is probably too dangerous for 7.1, here > is a more localized version of the fix, which doesn't change reg_set_p/ > modified_in_p/modified_between_p etc. behavior that is used in many spots, > but just changes emit_swap_insn that has seen that problem (this code in > emit_swap_insn is new in 7, so it is a P1 wrong-code regression). > > What the patch does is instead of relying on modified_between_p to catch > this it checks whether i1src is sp based and if it is, checks the insns > while skipping over them whether they are push/pop (autoinc of sp) and > if so, punts. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for 7.1?
Looks good to me. Thanks, Richard. > 2017-04-27 Jakub Jelinek <ja...@redhat.com> > > PR target/79430 > * reg-stack.c (emit_swap_insn): If i1src mentions the stack pointer, > punt if tmp contains autoinc of stack pointer. > > --- gcc/reg-stack.c.jj 2017-04-26 10:13:49.000000000 +0200 > +++ gcc/reg-stack.c 2017-04-26 13:13:19.487471078 +0200 > @@ -915,6 +915,7 @@ emit_swap_insn (rtx_insn *insn, stack_pt > rtx i2set; > rtx_insn *tmp = PREV_INSN (i1); > rtx_insn *limit = PREV_INSN (BB_HEAD (current_block)); > + bool sp_used = reg_overlap_mentioned_p (stack_pointer_rtx, i1src); > /* Find the previous insn involving stack regs, but don't pass a > block boundary. */ > while (tmp != limit) > @@ -928,6 +929,31 @@ emit_swap_insn (rtx_insn *insn, stack_pt > i2 = tmp; > break; > } > + /* FIXME: modified_between_p does not consider autoinc > + modifications of stack pointer if i1src refers to > + stack pointer, check it here manually. */ > + if (sp_used && NONDEBUG_INSN_P (tmp)) > + { > + subrtx_var_iterator::array_type array; > + FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (tmp), NONCONST) > + { > + rtx mem = *iter; > + if (mem > + && MEM_P (mem) > + && (GET_RTX_CLASS (GET_CODE (XEXP (mem, 0))) > + == RTX_AUTOINC)) > + { > + if (XEXP (XEXP (mem, 0), 0) == stack_pointer_rtx) > + { > + i2 = tmp; > + break; > + } > + iter.skip_subrtxes (); > + } > + } > + if (i2) > + break; > + } > tmp = PREV_INSN (tmp); > } > if (i2 != NULL_RTX >