This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix PR c/9530
> No, we can't. The fp stack must be empty at function entry.
Ah! yes, of course. Thanks for the clarification.
The first patch is for the mainline (bootstrapped/regtested c,c++,objc,f77)
and the second one for the 3.3 branch (only bootstrapped for the time
being).
--
Eric Botcazou
2003-02-05 Eric Botcazou <ebotcazou@libertysurf.fr>
Richard Henderson <rth@redhat.com>
PR c/9530
* config/i386/i386.c (ix86_function_ok_for_sibcall): Forbid
sibcalls from functions that return a float to functions that don't.
2003-02-05 Eric Botcazou <ebotcazou@libertysurf.fr>
Richard Henderson <rth@redhat.com>
PR c/9530
* config/i386/i386.h (FUNCTION_OK_FOR_SIBCALL): Forbid
sibcalls from functions that return a float to functions that don't.
2003-02-05 Eric Botcazou <ebotcazou@libertysurf.fr>
Richard Henderson <rth@redhat.com>
* gcc.c-torture/compile/20030205-1.c: New test.
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.519
diff -u -r1.519 i386.c
--- config/i386/i386.c 28 Jan 2003 18:08:50 -0000 1.519
+++ config/i386/i386.c 4 Feb 2003 08:11:05 -0000
@@ -1477,11 +1477,9 @@
{ NULL, 0, 0, false, false, false, NULL }
};
-/* If PIC, we cannot make sibling calls to global functions
- because the PLT requires %ebx live.
- If we are returning floats on the register stack, we cannot make
- sibling calls to functions that return floats. (The stack adjust
- instruction will wind up after the sibcall jump, and not be executed.) */
+/* Decide whether we can make a sibling call to a function. DECL is the
+ declaration of the function being targeted by the call and EXP is the
+ CALL_EXPR representing the call. */
static bool
ix86_function_ok_for_sibcall (decl, exp)
@@ -1496,10 +1494,11 @@
/* If we are returning floats on the 80387 register stack, we cannot
make a sibcall from a function that doesn't return a float to a
- function that does; the necessary stack adjustment will not be
- executed. */
+ function that does or, conversely, from a function that does return
+ a float to a function that doesn't; the necessary stack adjustment
+ would not be executed. */
if (STACK_REG_P (ix86_function_value (TREE_TYPE (exp)))
- && ! STACK_REG_P (ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)))))
+ != STACK_REG_P (ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)))))
return false;
/* If this call is indirect, we'll need to be able to use a call-clobbered
Index: config/i386/i386.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.h,v
retrieving revision 1.309
diff -u -r1.309 i386.h
--- config/i386/i386.h 10 Dec 2002 00:56:36 -0000 1.309
+++ config/i386/i386.h 4 Feb 2003 08:30:58 -0000
@@ -1718,15 +1718,17 @@
/* If PIC, we cannot make sibling calls to global functions
because the PLT requires %ebx live.
- If we are returning floats on the register stack, we cannot make
- sibling calls to functions that return floats. (The stack adjust
- instruction will wind up after the sibcall jump, and not be executed.) */
+ If we are returning floats on the 80387 register stack, we cannot
+ make a sibcall from a function that doesn't return a float to a
+ function that does or, conversely, from a function that does return
+ a float to a function that doesn't; the necessary stack adjustment
+ would not be executed. */
#define FUNCTION_OK_FOR_SIBCALL(DECL) \
((DECL) \
&& (! flag_pic || ! TREE_PUBLIC (DECL)) \
&& (! TARGET_FLOAT_RETURNS_IN_80387 \
- || ! FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (DECL)))) \
- || FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (cfun->decl))))))
+ || (FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (DECL)))) \
+ == FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (cfun->decl)))))))
/* Perform any needed actions needed for a function that is receiving a
variable number of arguments.
/* PR c/9530 */
/* Contributed by Volker Reichelt. */
/* Verify that the call to 'foo' is not turned
into a sibling call. */
void foo(float d);
float bar(float d);
float baz(float d)
{
foo(bar(d));
}