aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2003-01-20 18:59:43 +0000
committerNick Clifton <nickc@gcc.gnu.org>2003-01-20 18:59:43 +0000
commite32894124dc9860e977b8ebe23b9b21a2ca066ec (patch)
tree964485e9f01270d98d7b1fc07b65f9917509b03f /gcc
parent120cdf68d5dbc7b2819d7e97a26acf4436bb66f8 (diff)
downloadgcc-e32894124dc9860e977b8ebe23b9b21a2ca066ec.zip
gcc-e32894124dc9860e977b8ebe23b9b21a2ca066ec.tar.gz
gcc-e32894124dc9860e977b8ebe23b9b21a2ca066ec.tar.bz2
Add an UNSPEC_PROLOGUE_USE to prevent the link register from being considered dead.
Add a testcase for the bug fixed by this patch. From-SVN: r61509
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/arm/arm.md8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20030117-1.c23
4 files changed, 41 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ff97b31..c75ddc7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2003-01-20 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.md (sibcall_epilogue): Add an
+ UNSPEC_PROLOGUE_USE to prevent the link register from being
+ considered dead.
+
Mon Jan 20 14:36:23 CET 2003 Jan Hubicka <jh@suse.cz>
* i386.md (SSE cmov splitter): Handle memory operand in operand 5.
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index b7a09ce..40f956e 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -8430,8 +8430,14 @@
"
)
+;; Note - although unspec_volatile's USE all hard registers,
+;; USEs are ignored after relaod has completed. Thus we need
+;; to add an unspec of the link register to ensure that flow
+;; does not think that it is unused by the sibcall branch that
+;; will replace the standard function epilogue.
(define_insn "sibcall_epilogue"
- [(unspec_volatile [(const_int 0)] VUNSPEC_EPILOGUE)]
+ [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_PROLOGUE_USE)
+ (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
"TARGET_ARM"
"*
if (USE_RETURN_INSN (FALSE))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 79e76c0..3f53ca4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2003-01-20 Nick Clifton <nickc@redhat.com>
+
+ * gcc.c-torture/execute/20030117-1.c: New test case. Exposes
+ problem with ARM sibcall code generation.
+
2003-01-20 Kazu Hirata <kazu@cs.umass.edu>
* gcc.c-torture/execute/20030120-1.c: New.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030117-1.c b/gcc/testsuite/gcc.c-torture/execute/20030117-1.c
new file mode 100644
index 0000000..656bd61
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20030117-1.c
@@ -0,0 +1,23 @@
+int foo (int, int, int);
+int bar (int, int, int);
+
+int main (void)
+{
+ if (foo (5, 10, 21) != 12)
+ abort ();
+
+ if (bar (9, 12, 15) != 150)
+ abort ();
+
+ exit (0);
+}
+
+int foo (int x, int y, int z)
+{
+ return (x + y + z) / 3;
+}
+
+int bar (int x, int y, int z)
+{
+ return foo (x * x, y * y, z * z);
+}