From faf7a23d6d3bc281c386865971f7bffd8cb7057c Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@redhat.com>
Date: Thu, 4 Aug 2011 08:39:40 -0700
Subject: [PATCH] re PR middle-end/49968 (ICE in calls.c:3141 / assert after
 emit_stack_restore)

PR middle-end/49968
        * calls.c (expand_call): Use fixup_args_size_notes for
        emit_stack_restore.
        * expr.c (fixup_args_size_notes): Allow STACK_POINTER_REGNUM sets
        in non-standard modes.

From-SVN: r177404
---
 gcc/ChangeLog |  8 ++++++++
 gcc/calls.c   | 10 ++--------
 gcc/expr.c    |  7 +++++--
 3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4229c497112c..861320b612b2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2011-08-04  Richard Henderson  <rth@redhat.com>
+
+	PR middle-end/49968
+	* calls.c (expand_call): Use fixup_args_size_notes for
+	emit_stack_restore.
+	* expr.c (fixup_args_size_notes): Allow STACK_POINTER_REGNUM sets
+	in non-standard modes.
+
 2011-08-04  Jakub Jelinek  <jakub@redhat.com>
 
 	* gcc.c (self_spec): New variable.
diff --git a/gcc/calls.c b/gcc/calls.c
index 6eb1f2120874..26c320095e00 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -3128,18 +3128,12 @@ expand_call (tree exp, rtx target, int ignore)
 
       if (old_stack_level)
 	{
-	  rtx last, set;
+	  rtx prev = get_last_insn ();
 
 	  emit_stack_restore (SAVE_BLOCK, old_stack_level);
 	  stack_pointer_delta = old_stack_pointer_delta;
 
-	  /* ??? Is this assert warrented, given emit_stack_restore?
-	     or should we just mark the last insn no matter what?  */
-	  last = get_last_insn ();
-	  set = single_set (last);
-	  gcc_assert (set != NULL);
-	  gcc_assert (SET_DEST (set) == stack_pointer_rtx);
-	  add_reg_note (last, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
+	  fixup_args_size_notes (prev, get_last_insn (), stack_pointer_delta);
 
 	  pending_stack_adjust = old_pending_adj;
 	  old_stack_allocated = stack_pointer_delta - pending_stack_adjust;
diff --git a/gcc/expr.c b/gcc/expr.c
index 0cfc845c4828..e5bec34e78c5 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -3620,11 +3620,14 @@ fixup_args_size_notes (rtx prev, rtx last, int end_args_size)
       dest = SET_DEST (set);
 
       /* Look for direct modifications of the stack pointer.  */
-      if (dest == stack_pointer_rtx)
+      if (REG_P (dest) && REGNO (dest) == STACK_POINTER_REGNUM)
 	{
 	  gcc_assert (!saw_unknown);
 	  /* Look for a trivial adjustment, otherwise assume nothing.  */
-	  if (GET_CODE (SET_SRC (set)) == PLUS
+	  /* Note that the SPU restore_stack_block pattern refers to
+	     the stack pointer in V4SImode.  Consider that non-trivial.  */
+	  if (SCALAR_INT_MODE_P (GET_MODE (dest))
+	      && GET_CODE (SET_SRC (set)) == PLUS
 	      && XEXP (SET_SRC (set), 0) == stack_pointer_rtx
 	      && CONST_INT_P (XEXP (SET_SRC (set), 1)))
 	    this_delta = INTVAL (XEXP (SET_SRC (set), 1));
-- 
GitLab