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
> 

Reply via email to