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?

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

        Jakub

Reply via email to