From e32894124dc9860e977b8ebe23b9b21a2ca066ec Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 20 Jan 2003 18:59:43 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 +++++ gcc/config/arm/arm.md | 8 ++++++- gcc/testsuite/ChangeLog | 5 ++++ .../gcc.c-torture/execute/20030117-1.c | 23 +++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20030117-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ff97b3121bf..c75ddc72512 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2003-01-20 Nick Clifton + + * 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 * 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 b7a09ce4cf2..40f956ee260 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 79e76c02697..3f53ca43469 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2003-01-20 Nick Clifton + + * gcc.c-torture/execute/20030117-1.c: New test case. Exposes + problem with ARM sibcall code generation. + 2003-01-20 Kazu Hirata * 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 00000000000..656bd61ed0a --- /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); +}