From c93646bd3ca88aa2cc99cc5a2090dc6ea4b39688 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Wed, 12 Sep 2007 23:19:51 +0200
Subject: [PATCH] re PR target/32338 (Error: .prologue within prologue)

	PR target/32338
	* config/ia64/ia64.c (ia64_expand_epilogue): Emit blockage
	before sp restoration even when total_size is 0, but
	frame_pointer_needed.

	* gcc.dg/pr32338-1.c: New test.
	* gcc.dg/pr32338-2.c: New test.

From-SVN: r128446
---
 gcc/ChangeLog                    |  7 +++++
 gcc/config/ia64/ia64.c           |  4 ++-
 gcc/testsuite/ChangeLog          |  6 ++++
 gcc/testsuite/gcc.dg/pr32338-1.c | 47 ++++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/pr32338-2.c | 47 ++++++++++++++++++++++++++++++++
 5 files changed, 110 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr32338-1.c
 create mode 100644 gcc/testsuite/gcc.dg/pr32338-2.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index af05fca5d5ed..d16c38c8c155 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2007-09-12  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/32338
+	* config/ia64/ia64.c (ia64_expand_epilogue): Emit blockage
+	before sp restoration even when total_size is 0, but
+	frame_pointer_needed.
+
 2007-09-12  Bob Wilson  <bob.wilson@acm.org>
 
 	* config/xtensa/xtensa.c (machine_function): Add vararg_a7_copy.
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 46f75c5a205c..6a6a9e62f0c9 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -3437,7 +3437,9 @@ ia64_expand_epilogue (int sibcall_p)
 
   finish_spill_pointers ();
 
-  if (current_frame_info.total_size || cfun->machine->ia64_eh_epilogue_sp)
+  if (current_frame_info.total_size
+      || cfun->machine->ia64_eh_epilogue_sp
+      || frame_pointer_needed)
     {
       /* ??? At this point we must generate a magic insn that appears to
          modify the spill iterators, the stack pointer, and the frame
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 433471cd1d3f..977c2a50eed2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2007-09-12  Jakub Jelinek  <jakub@redhat.com>
+
+	PR target/32338
+	* gcc.dg/pr32338-1.c: New test.
+	* gcc.dg/pr32338-2.c: New test.
+
 2007-09-12  Bob Wilson  <bob.wilson@acm.org>
 	
 	* lib/target-supports.exp (check_effective_target_sync_int_long):
diff --git a/gcc/testsuite/gcc.dg/pr32338-1.c b/gcc/testsuite/gcc.dg/pr32338-1.c
new file mode 100644
index 000000000000..6a79a8c22815
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr32338-1.c
@@ -0,0 +1,47 @@
+/* PR target/32338 */
+/* { dg-do link } */
+/* { dg-options "-O2 -fno-omit-frame-pointer" } */
+
+struct S
+{
+};
+
+int
+__attribute__((noinline))
+foo (struct S *d)
+{
+  return 2;
+}
+
+int
+__attribute__((noinline))
+bar (struct S *d)
+{
+  return 4;
+}
+
+int
+__attribute__((noinline))
+fnl (char const *q)
+{
+  return __builtin_strlen (q);
+}
+
+int
+__attribute__((noinline))
+baz (struct S *d, char const *q)
+{
+  unsigned int len;
+  len = fnl (q);
+  if (len > 512)
+    return bar (d);
+  return foo (d);
+}
+
+int
+main (int argc, char *argv[])
+{
+  if (argc > 30)
+    return baz ((void *) 0, "abcde");
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr32338-2.c b/gcc/testsuite/gcc.dg/pr32338-2.c
new file mode 100644
index 000000000000..81daddf6a67a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr32338-2.c
@@ -0,0 +1,47 @@
+/* PR target/32338 */
+/* { dg-do link } */
+/* { dg-options "-O2 -fno-omit-frame-pointer" } */
+
+struct S
+{
+};
+
+int
+__attribute__((noinline))
+foo (void)
+{
+  return 2;
+}
+
+int
+__attribute__((noinline))
+bar (void)
+{
+  return 4;
+}
+
+int
+__attribute__((noinline))
+fnl (void)
+{
+  return 6;
+}
+
+int
+__attribute__((noinline))
+baz (void)
+{
+  unsigned int len;
+  len = fnl ();
+  if (len > 512)
+    return bar ();
+  return foo ();
+}
+
+int
+main (int argc, char *argv[])
+{
+  if (argc > 30)
+    return baz ();
+  return 0;
+}
-- 
GitLab