From e732178cb8bd3c46c2b07b52bd1830e8155a45cb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 24 Apr 2002 09:58:12 -0700 Subject: [PATCH] re PR target/6420 (libstdc++ failures on sparc-linux-gnu) 2002-04-24 David S. Miller PR target/6420 * config/sparc/sparc.h (FUNCTION_OK_FOR_SIBCALL): Return false if 32-bit Sparc and current_function_returns_struct is true. From-SVN: r52720 --- gcc/ChangeLog | 6 ++++++ gcc/config/sparc/sparc.h | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2c90a625e30..8482554c725 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2002-04-24 David S. Miller + + PR target/6420 + * config/sparc/sparc.h (FUNCTION_OK_FOR_SIBCALL): Return false if + 32-bit Sparc and current_function_returns_struct is true. + Wed Apr 24 13:48:25 CEST 2002 Jan Hubicka * loop.c (canonicalize_condition): Use gen_int_mode. diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 4552132743a..872b1eeeee0 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1902,8 +1902,23 @@ do { \ #define STRICT_ARGUMENT_NAMING TARGET_V9 /* We do not allow sibling calls if -mflat, nor - we do not allow indirect calls to be optimized into sibling calls. */ -#define FUNCTION_OK_FOR_SIBCALL(DECL) (DECL && ! TARGET_FLAT) + we do not allow indirect calls to be optimized into sibling calls. + + Also, on sparc 32-bit we cannot emit a sibling call when the + current function returns a structure. This is because the "unimp + after call" convention would cause the callee to return to the + wrong place. The generic code already disallows cases where the + function being called returns a structure. + + It may seem strange how this last case could occur. Usually there + is code after the call which jumps to epilogue code which dumps the + return value into the struct return area. That ought to invalidate + the sibling call right? Well, in the c++ case we can end up passing + the pointer to the struct return area to a constructor (which returns + void) and then nothing else happens. Such a sibling call would look + valid without the added check here. */ +#define FUNCTION_OK_FOR_SIBCALL(DECL) \ + (! TARGET_FLAT && (TARGET_ARCH64 || ! current_function_returns_struct)) /* Generate RTL to flush the register windows so as to make arbitrary frames available. */