On Linux/ia32, this patch http://gcc.gnu.org/ml/gcc-cvs/2007-07/msg00336.html caused FAIL: libffi.call/return_sc.c -O0 -W -Wall execution test FAIL: libffi.call/return_sc.c -O2 execution test FAIL: libffi.call/return_sc.c -O3 execution test
The problem seems to be a backend one(?). What happens is that for signed char return_sc (signed char sc) { return sc; } the return value is now zero-extended instead of sign-extended (the sign extension was done in the C frontend code). The C standard in 6.8.6.4 specifies that for the return statement _only_ if the expression has a different type from the return type of the function then 'the value is converted as if by assignment to an object having the return type of the function'. Which reading either way doesn't specify whether the return value is implicitly sign-extended or not (AFAIK whether in this case the value is sign or zero extended should be / is specified by the target ABI). On x86_64 we get return_sc: .LFB12: movl %edi, %eax ret ... movl $-127, %edi call return_sc which is why we may be lucky here(?). On i686 we pass on the stack like return_sc: pushl %ebp movl %esp, %ebp movzbl 8(%ebp), %eax popl %ebp ret ... movl $-127, (%esp) call return_sc explicitly doing zero-extension. Now the libffi testcase explicitly checks for sign-extension(!) of the return value: for (sc = (signed char) -127; sc < (signed char) 127; sc++) { ffi_call(&cif, FFI_FN(return_sc), &rint, values); CHECK(rint == (ffi_arg) sc); } as rint is of type ffi_arg (unsigned long) and sc is signed char. I wonder whether this is desired or not. Andreas? Micha, how is promotion of the return value specified in the x86 ABI?
The following is a function that is now differently compiled on both x86_64 and i686: signed char return_sc (signed char *sc) { return *sc; }
So, my final conclusion would be that this is a testsuite bug because whether we do zero or sign extension for returns in a register does not matter for valid uses of this return value.
Index: return_sc.c =================================================================== --- return_sc.c (revision 126678) +++ return_sc.c (working copy) @@ -30,7 +30,7 @@ int main (void) sc < (signed char) 127; sc++) { ffi_call(&cif, FFI_FN(return_sc), &rint, values); - CHECK(rint == (ffi_arg) sc); + CHECK((signed char) rint == sc); } exit(0); } ?
The 32bit psABI specifies Integral Arguments as 'Functions pass all integer-valued arguments as words, expanding or padding signed or unsigned bytes and halfwords as needed'. For return values the best I can find is 'A function that returns an integral or pointer value places its result in register %eax.' Both are not exactly clear whether sign- or zero-extension is required.
Fine with me, thanks and sorry for the delay. Pls ci.
Fixed.
Subject: Bug 32843 Author: rguenth Date: Thu Jul 26 09:13:58 2007 New Revision: 126950 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=126950 Log: 2007-07-26 Richard Guenther <rguenther@suse.de> PR testsuite/32843 * testsuite/libffi.call/return_sc.c (main): Verify call result as signed char, not ffi_arg. Modified: trunk/libffi/ChangeLog trunk/libffi/testsuite/libffi.call/return_sc.c
But the change was in generic code, are you very sure you haven't changed ABI on any of the targets?
Well, honestly not. Still other frontends do not do return type promotion themselves, so the backend is responsible for doing this. Do you have any suggestion on what target to look at to verify this?
Subject: Bug 32843 Author: aph Date: Tue Jul 31 15:05:52 2007 New Revision: 127093 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=127093 Log: 2007-07-30 Andrew Haley <aph@redhat.com> PR testsuite/32843 * src/x86/ffi.c (ffi_prep_cif_machdep): in x86 case, add code for signed/unsigned int8/16. * src/x86/sysv.S (ffi_call_SYSV): Rewrite to: Use a jump table. Remove code to pop args from the stack after call. Special-case signed/unsigned int8/16. * testsuite/libffi.call/return_sc.c (main): Revert. Modified: trunk/libffi/ChangeLog trunk/libffi/src/x86/ffi.c trunk/libffi/src/x86/sysv.S trunk/libffi/testsuite/libffi.call/return_sc.c
Subject: Bug 32843 Author: aph Date: Mon Aug 6 12:48:07 2007 New Revision: 127241 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=127241 Log: PR testsuite/32843 * src/x86/sysv.S (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. Modified: trunk/libffi/ChangeLog trunk/libffi/src/x86/sysv.S
> The 32bit psABI specifies Integral Arguments as 'Functions pass all > integer-valued > arguments as words, expanding or padding signed or unsigned bytes and > halfwords as needed'. For return values the best I can find is 'A function that > returns an integral or pointer value places its result in register %eax.' > Both are not exactly clear whether sign- or zero-extension is required. On the contrary, this implies very strongly to me that all integer-valued arguments are passed as words, fully sign- or zero-extended for their type. To read this in any other way strikes me as perverse. If we are not correctly sign- or zero-extendening return values we have broken the ABI. To suggest that this sign- or zero-extension does not apply to return values is also perverse.
In addition: I suspect that this bug also is manifested on x86 Darwin, but my patch should not affect that system at all, and therefore I suspect that this bug is still manifested on that system.
Subject: Bug 32843 Author: doko Date: Mon Aug 6 20:13:06 2007 New Revision: 127249 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=127249 Log: - Revert the changes for PR testsuite/32843, not needed on the branch. Modified: branches/ubuntu/gcc-4_2-branch/libffi/ChangeLog branches/ubuntu/gcc-4_2-branch/libffi/src/x86/ffi.c branches/ubuntu/gcc-4_2-branch/libffi/src/x86/sysv.S branches/ubuntu/gcc-4_2-branch/libffi/testsuite/libffi.call/return_sc.c
Regarding comment #14, yep. Patch posted here: http://gcc.gnu.org/ml/gcc-patches/2008-01/msg00041.html
Subject: Bug 32843 Author: andreast Date: Sat Jan 5 20:49:41 2008 New Revision: 131343 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=131343 Log: 2008-01-05 Andreas Tobler <a.tobler@schweiz.org> PR testsuite/32843 * src/x86/ffi.c (ffi_prep_cif_machdep): Add code for signed/unsigned int8/16 for X86_DARWIN. Updated copyright info. Handle one and two byte structs with special cif->flags. * src/x86/ffitarget.h: Add special types for one and two byte structs. Updated copyright info. * src/x86/darwin.S (ffi_call_SYSV): Rewrite to use a jump table like sysv.S Remove code to pop args from the stack after call. Special-case signed/unsigned for int8/16, one and two byte structs. (ffi_closure_raw_SYSV): Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16, FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. Updated copyright info. Modified: trunk/libffi/ChangeLog trunk/libffi/src/x86/darwin.S trunk/libffi/src/x86/ffi.c trunk/libffi/src/x86/ffitarget.h
Subject: Bug 32843 Author: ljrittle Date: Thu Sep 17 20:54:56 2009 New Revision: 151819 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=151819 Log: 2009-09-17 Loren J. Rittle <ljrittle@acm.org> PR testsuite/32843 (strikes again) * src/x86/ffi.c (ffi_prep_cif_machdep): Add X86_FREEBSD to enable proper extension on char and short. Modified: trunk/libffi/ChangeLog trunk/libffi/src/x86/ffi.c
Subject: Bug 32843 Author: gerald Date: Sun Jun 20 17:12:11 2010 New Revision: 161048 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=161048 Log: Backport from mainline: 2009-09-17 Loren J. Rittle <ljrittle@acm.org> PR testsuite/32843 (strikes again) src/x86/ffi.c (ffi_prep_cif_machdep): Add X86_FREEBSD to enable proper extension on char and short. Modified: branches/gcc-4_4-branch/libffi/ChangeLog branches/gcc-4_4-branch/libffi/src/x86/ffi.c