Bug 24306 - [4.0 Regression] va_arg gets confused when skipping over certain zero-sized types with -msse
Summary: [4.0 Regression] va_arg gets confused when skipping over certain zero-sized t...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.1.0
: P2 major
Target Milestone: 4.1.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ABI, wrong-code
Depends on: 34010
Blocks:
  Show dependency treegraph
 
Reported: 2005-10-11 12:01 UTC by Ben Elliston
Modified: 2012-12-23 18:08 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work: 3.3.3 4.2.0 4.1.0 4.1.1 4.1.2 4.2.0
Known to fail: 3.4.0 4.0.0
Last reconfirmed: 2005-12-19 11:34:31


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ben Elliston 2005-10-11 12:01:07 UTC
va_arg seems to mess up the va_list when variadic variables have size 0, but when have large alignment requirements.  When the alignment is small, this seems to work by chance.

$ gcc foo.c -o foo && ./foo
3 0

#include <stdarg.h>
#include <stdio.h>

typedef int __attribute__ ((vector_size (16))) foo_t;

struct s
{
  foo_t f[0];
} s1;
  
void
check (int x, ...)
{
  int y;
  va_list ap;

  va_start (ap, x);
  va_arg (ap, struct s);
  y = va_arg (ap, int);

  /* Expect output: 3 7  */
  printf ("%d %d\n", x, y);
}

int main()
{
  check (3, s1, 7);
  return 0;
}
Comment 1 Andrew Pinski 2005-10-11 13:34:10 UTC
Hmm, this works for me with todays' compiler:
earth:~>gcc t.c -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: /home/peshtigo/pinskia/src/gnu/gcc/src/configure --target=i686-pc-linux-gnu --host=i686-pc-linux-gnu --enable-__cxa_atexit --enable-languages=c++,objc,java,f95 --prefix=/home/gates/pinskia/linux --enable-threads=posix --enable-shared
Thread model: posix
gcc version 4.1.0 20051011 (experimental)
 /home/gates/pinskia/linux/libexec/gcc/i686-pc-linux-gnu/4.1.0/cc1 -quiet -v t.c -quiet -dumpbase t.c -mtune=pentiumpro -auxbase t -version -o /tmp/ccyK6uLf.s
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /home/gates/pinskia/linux/include
 /home/gates/pinskia/linux/lib/gcc/i686-pc-linux-gnu/4.1.0/include
 /home/gates/pinskia/linux/lib/gcc/i686-pc-linux-gnu/4.1.0/../../../../i686-pc-linux-gnu/include
 /usr/include
End of search list.
GNU C version 4.1.0 20051011 (experimental) (i686-pc-linux-gnu)
        compiled by GNU C version 4.1.0 20051011 (experimental).
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: 4eb5c7164a4d9c2ecd7466e6212b1162
 /home/gates/pinskia/linux/lib/gcc/i686-pc-linux-gnu/4.1.0/../../../../i686-pc-linux-gnu/bin/as -V -Qy -o /tmp/ccOwBdYl.o /tmp/ccyK6uLf.s
GNU assembler version 2.15.94 (i686-pc-linux-gnu) using BFD version 2.15.94 20041104
 /home/gates/pinskia/linux/libexec/gcc/i686-pc-linux-gnu/4.1.0/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /home/gates/pinskia/linux/lib/gcc/i686-pc-linux-gnu/4.1.0/crtbegin.o -L/home/gates/pinskia/linux/lib/gcc/i686-pc-linux-gnu/4.1.0 -L/home/gates/pinskia/linux/lib/gcc/i686-pc-linux-gnu/4.1.0/../../../../i686-pc-linux-gnu/lib -L/home/gates/pinskia/linux/lib/gcc/i686-pc-linux-gnu/4.1.0/../../.. /tmp/ccOwBdYl.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /home/gates/pinskia/linux/lib/gcc/i686-pc-linux-gnu/4.1.0/crtend.o /usr/lib/crtn.o
earth:~>./a.out
3 7
-----
Can you suply the ouput of gcc -v?
Comment 2 Ben Elliston 2005-10-11 14:02:39 UTC
gcc version 4.1.0 20051010 (experimental)

I managed to work out that you need to add -msse to trigger the bug.
Comment 3 Andrew Pinski 2005-10-11 14:09:32 UTC
Confirmed, a regression from 3.3.3.
Comment 4 Mark Mitchell 2005-10-31 06:10:52 UTC
This is a corner-case; we can leave this at P2.
Comment 5 Richard Biener 2005-12-19 11:34:31 UTC
We add some alignment fluff in the SSE type case.  The following works as expected:

#include <stdarg.h>

typedef int __attribute__ ((vector_size (16))) foo_t;
extern void abort(void);

struct s
{
  _Complex double f[0];
} s1;

void
check (int x, ...)
{
  int y;
  va_list ap;

  va_start (ap, x);
  va_arg (ap, struct s);
  y = va_arg (ap, int);

  /* Expect output: 3 7  */
  if (y != 7)
    abort ();
}

int main()
{
  check (3, s1, 7);
  return 0;
}

.vars dump difference, working agains non-working:

--- t2.c.t96.vars       2005-12-19 12:22:09.000000000 +0100
+++ t.c.t96.vars        2005-12-19 12:15:08.000000000 +0100
@@ -5,10 +5,12 @@
 {
   char * ap;
   char * D.1699;
+  char * ap.0;
 
 <bb 2>:
   __builtin_va_start (&ap, 0, 0);
-  D.1699 = ap;
+  ap.0 = ap;
+  D.1699 = ap.0 + 15B & -16B;
   if (*(int *) D.1699 != 7) goto <L0>; else goto <L1>;
 
 <L0>:;


We have a bug here in the generic builtins.c and the config/i386/i386.c variant
of gimplify_va_arg_expr - and I have a fix.
Comment 6 Richard Biener 2005-12-19 11:40:00 UTC
And this doesn't look target dependent.
Comment 7 Richard Biener 2005-12-20 16:20:33 UTC
Subject: Bug 24306

Author: rguenth
Date: Tue Dec 20 16:20:27 2005
New Revision: 108854

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=108854
Log:
2005-12-20  Richard Guenther  <rguenther@suse.de>

	PR middle-end/24306
	* builtins.c (std_gimplify_va_arg_expr): Do not align
	va frame for zero sized types.
	* config/i386/i386.c (ix86_gimplify_va_arg): Likewise.

        * gcc.target/i386/pr24306.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.target/i386/pr24306.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/builtins.c
    trunk/gcc/config/i386/i386.c
    trunk/gcc/testsuite/ChangeLog

Comment 8 Richard Biener 2005-12-20 17:23:18 UTC
Subject: Bug 24306

Author: rguenth
Date: Tue Dec 20 17:23:12 2005
New Revision: 108857

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=108857
Log:
2005-12-20  Richard Guenther  <rguenther@suse.de>

	PR middle-end/24306
	* builtins.c (std_gimplify_va_arg_expr): Do not align
	va frame for zero sized types.
	* config/i386/i386.c (ix86_gimplify_va_arg): Likewise.

	* gcc.target/i386/pr24306.c

Added:
    branches/gcc-4_1-branch/gcc/testsuite/gcc.target/i386/pr24306.c
Modified:
    branches/gcc-4_1-branch/gcc/ChangeLog
    branches/gcc-4_1-branch/gcc/builtins.c
    branches/gcc-4_1-branch/gcc/config/i386/i386.c
    branches/gcc-4_1-branch/gcc/testsuite/ChangeLog

Comment 9 Richard Biener 2005-12-20 17:24:10 UTC
Fixed on head and 4.1.
Comment 10 Richard Biener 2006-02-03 12:35:40 UTC
Not working on a backport.
Comment 11 Gabriel Dos Reis 2007-02-03 15:46:03 UTC
Fixed in GCC-4.1.0 and higher.
Comment 12 Mike Stump 2007-11-07 01:06:31 UTC
This patch is wrong.  See http://gcc.gnu.org/PR34010 for details.
Comment 13 Jack Howarth 2007-12-21 20:45:11 UTC
Reversing the change...

http://gcc.gnu.org/viewcvs/trunk/gcc/builtins.c?r1=108629&r2=108854&pathrev=108854

reduces the failures at -m64 on powerpc-apple-darwin9 from...

Running /sw/src/fink.build/gcc43-4.2.999-20071219/gcc-4.3-20071219/gcc/testsuite/gcc.dg/compat/struct-layout-1.exp ...
FAIL: tmpdir-gcc.dg-struct-layout-1/t001 c_compat_x_tst.o-c_compat_y_tst.o execute 
FAIL: tmpdir-gcc.dg-struct-layout-1/t003 c_compat_x_tst.o-c_compat_y_tst.o execute 
FAIL: tmpdir-gcc.dg-struct-layout-1/t005 c_compat_x_tst.o-c_compat_y_tst.o execute 
FAIL: tmpdir-gcc.dg-struct-layout-1/t006 c_compat_x_tst.o-c_compat_y_tst.o execute 
FAIL: tmpdir-gcc.dg-struct-layout-1/t008 c_compat_x_tst.o-c_compat_y_tst.o execute 
FAIL: tmpdir-gcc.dg-struct-layout-1/t016 c_compat_x_tst.o-c_compat_y_tst.o execute 
FAIL: tmpdir-gcc.dg-struct-layout-1/t024 c_compat_x_tst.o-c_compat_y_tst.o execute 
FAIL: tmpdir-gcc.dg-struct-layout-1/t026 c_compat_x_tst.o-c_compat_y_tst.o execute 
FAIL: tmpdir-gcc.dg-struct-layout-1/t028 c_compat_x_tst.o-c_compat_y_tst.o execute 

...to...

Running /sw/src/fink.build/gcc43-4.2.999-20071219/gcc-4.3-20071219/gcc/testsuite/gcc.dg/compat/struct-layout-1.exp ...
FAIL: tmpdir-gcc.dg-struct-layout-1/t003 c_compat_x_tst.o-c_compat_y_tst.o execute 
FAIL: tmpdir-gcc.dg-struct-layout-1/t005 c_compat_x_tst.o-c_compat_y_tst.o execute 
FAIL: tmpdir-gcc.dg-struct-layout-1/t008 c_compat_x_tst.o-c_compat_y_tst.o execute 
FAIL: tmpdir-gcc.dg-struct-layout-1/t016 c_compat_x_tst.o-c_compat_y_tst.o execute 
FAIL: tmpdir-gcc.dg-struct-layout-1/t026 c_compat_x_tst.o-c_compat_y_tst.o execute 
Comment 14 Jack Howarth 2007-12-22 16:41:58 UTC
For tmpdir-gcc.dg-struct-layout-1/t003 c_compat_x_tst.o-c_compat_y_tst.o on powerpc-apple-darwin9 at -m64, the two lines in t003_test.h that cause the failure are...

T(693,double atal2 a;Tal16long b;short int c;struct{}d;,F(693,a,-9109.968750,89665.703125)F(693,b,-2780362564512530142LL,-1882493019100008206LL)F(693,c,29451,-6341))

and

T(760,float a;long double b;unsigned long int c;signed char d;,F(760,a,-218391.812500,-167965.062500)F(760,b,-122404.406250,-90172.859375)F(760,c,2933687826322174624ULL,14862826394269793540ULL)F(760,d,55,64))

Comment 15 Jack Howarth 2007-12-22 16:56:33 UTC
For tmpdir-gcc.dg-struct-layout-1/t005 c_compat_x_tst.o-c_compat_y_tst.o on powerpc-apple-darwin9 at -m64, the line in t005_test.h that causes the testcase failure is...

T(998,df a;Talllong b:BQN(20);long long int c:BQN(1);TE4 d:19;long int e;,F(998,a,140017.484375,-160009.218750)B(998,b,-303431,345440)B(998,c,0,0)B(998,d,e4_253,e4_2)F(998,e,3562377756672343063LL,5761410617366885841LL))

Comment 16 Jack Howarth 2007-12-22 17:16:36 UTC
For tmpdir-gcc.dg-struct-layout-1/t008 c_compat_x_tst.o-c_compat_y_tst.o on powerpc-apple-darwin9 at -m64, the failing line in t008_test.h is...

T(1234,double a;signed char atal16 b;union{unsigned int d;struct{}e;}c;short int f;unsigned char g;,F(1234,a,-125234.421875,-6063.015625)F(1234,b,-105,88)F(1234,c.d,3504478143U,3116938342U)F(1234,f,-15109,-23068)F(1234,g,236U,127U))

Comment 17 Jack Howarth 2007-12-22 17:37:12 UTC
For tmpdir-gcc.dg-struct-layout-1/t016 c_compat_x_tst.o-c_compat_y_tst.o on powerpc-apple-darwin9 at -m64, the failing line in t016_test.h is...

T(1604,char a;TE7 b;enum E6 c;unsigned int d;long int e;char f[6];float g;short int atal16 h;int * i;,F(1604,a,76U,30U)F(1604,b,e7_m2147483647,e7_m2147483645)F(1604,c,e6_2,e6_2)F(1604,d,3007045619U,3425526240U)F(1604,e,7127725064803830888LL,2212588498547332024LL)F(1604,f[4],64U,30U)F(1604,g,-67359.484375,-251776.203125)F(1604,h,17064,8859)F(1604,i,(int *)&intarray[89], (int *)&intarray[249]))

Comment 18 Jack Howarth 2007-12-22 17:51:24 UTC
For tmpdir-gcc.dg-struct-layout-1/t026 c_compat_x_tst.o-c_compat_y_tst.o on powerpc-apple-darwin9 at -m64, the failing line in t026_test.h is...

T(2468,float a;long double b;Tchar c;Tal8llong d;,F(2468,a,3100.906250,83925.484375)F(2468,b,-156603.906250,244908.156250)F(2468,c,99U,35U)F(2468,d,5510104998541940327LL,8962187912153613792LL))

Comment 19 Richard Sandiford 2012-02-07 19:15:15 UTC
Author: rsandifo
Date: Tue Feb  7 19:15:10 2012
New Revision: 183977

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=183977
Log:
gcc/
	PR middle-end/24306
	* config/mips/mips.c (mips_std_gimplify_va_arg_expr): New function.
	(mips_gimplify_va_arg_expr): Call it instead of
	std_gimplify_va_arg_expr.

gcc/testsuite/
	PR middle-end/24306
	PR target/52154
	* lib/target-supports.exp (check_effective_target_mips_eabi): New.
	* gcc.target/mips/va-arg-1.c: New test.

Added:
    trunk/gcc/testsuite/gcc.target/mips/va-arg-1.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/mips/mips.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/lib/target-supports.exp