aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
+}