From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gary Thomas To: Jeffrey A Law Cc: David Edelsohn , Michael Meissner , egcs@cygnus.com Subject: Re: Another code generation bug in EGCS-1.0.1 Date: Mon, 09 Feb 1998 02:14:00 -0000 Message-id: References: <5517.887015036@hurl.cygnus.com> X-SW-Source: 1998-02/msg00348.html On 09-Feb-98 Jeffrey A Law wrote: > > In message < XFMail.980208101002.g.thomas@opengroup.org >you write: > > Content-Type: text/plain; charset=us-ascii > > > > EGCS-1.0.1 (and GCC-2.8.0) can generate bad code when configured > > for PowerPC and SYSV4-ABI (Linux/PPC). In this configuration, the > > stack is managed differently when varargs are present (a stack space > > optimization). However, for inlined functions that end up not > > generated inline and nested functions, this optimization is lost and > > the generated functions generate incorrect preamble code which will > > destroy the runtime stack. > > > > Code exists in the current version to try and address this for the nested > > functions case, but it was a little wrong (patch to "function.c"). Also, > > the case of inline functions was not present at all. > > > > A patch is attached which solves both problems. > Can you please send a testcase which exposes this problem? > > Thanks, > jeff The crux of the bug is that on the RS6000/PowerPC, the stack has a slightly different setup if there are varargs present or not. (This is an optimization; trying to save stack space and some register saves if there are no varargs). Anyway, the code generator needs to have information about the stack when the preamble is generated. Given that for inline functions this may be quite separated from the definition, that information needs to be saved at declaration time and restored when the code for the function is actually generated. This is related to the problem of nested functions where the inside and outside functions do not have the same stack setup requirements. There was already code in place to handle the nested functions (although it was a little broken). However, I couldn't tell how to use that functionality for the inlined function case, so I just mimicked it. If these can be combined, so much the better. Seeing what is wrong can come from a very simple test case: #include #include inline void debug(const char *msg,...){ va_list ap; va_start( ap, msg ); // use variable arg list vfprintf( stderr, msg, ap ); va_end( ap ); } void fun(void) { debug("%s.%d\n", __FUNCTION__, __LINE__); } The generated code is [excerpt]: .align 2 .weak debug__FPCce .type debug__FPCce,@function debug__FPCce: stwu 1,-32(1) mflr 0 stw 0,36(1) stw 3,8(1) stw 4,12(1) stw 5,16(1) stw 6,20(1) stw 7,24(1) stw 8,28(1) stw 9,32(1) stw 10,36(1) bc 4,6,.L19 stfd 1,40(1) stfd 2,48(1) stfd 3,56(1) stfd 4,64(1) stfd 5,72(1) stfd 6,80(1) stfd 7,88(1) stfd 8,96(1) stfd 9,104(1) You'll notice that the inline function 'debug' only reserves 32 bytes on the stack and then proceeds to save 112! This is because the code generator has lost the "context" for the function which told it that there were varargs. I hope that this clears this up. Perhaps Mike Meissner will have something to say about this since he added the original code to handle the nested function case. Note: AFAIK this currently only affects the RS6000/PowerPC when using the SYSV4 ABI (Linux/PPC). However, there could be other platforms with similar cases in the future. I also noticed that there is a use of the nested function (save_machine_state) for the i386 already. ------------------------------------------------------------------------ Gary Thomas | The Open Group / Research Institute | "Fine wine is a necessity of 2 Avenue de Vignate | life for me" 38610 Gieres - FRANCE | +33 4 76 63 48 74 | Thomas Jefferson email: g.thomas@opengroup.org | < http://www.opengroup.org/~gdt > | ... opinions expressed here are mine | and no one else would claim them! | ------------------------------------------------------------------------