This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: va-arg-25.c still fails on i686-linux


> 
> On 09/01/2004, at 11:06 PM, Zack Weinberg wrote:
> 
> >
> >I am still seeing va-arg-25.c fail at all optimization levels on
> >i686-linux.  It has done so, as far as I can tell, ever since it
> >was introduced.  Could you please either fix it or XFAIL it?
> >
> I think it would be better if an x86 port maintainer looked at this 
> failure.  The testcase does not fail on powerpc-Darwin.

It don't even need x86 port maintainer :)
The problem is wrong aligning of va_arg inside builtins.c when argument
alignment exceeds PARM_BOUNDARY.

Additionally I noticed some problems with SSE enabled (we mistakely used
SSE regiser for variadic call and output warning)

Note that I am not quite sure about the PAD_VARARGS_DOWN check, it just
seems appropriate at that place.

Bootstrapping/regtesting in progress, OK if it passes?

	* builtins.c (std_expand_builtin_va_arg): Align operand when needed.
	* i386.c (init_cumulative_args): Set warn_sse; fix handling of variadic
	functions accepting SSE arguments
	(function_arg): Warn only when asked to warn.
	* i386.h (ix86_args): Add warn_sse/warn_mmx fiels.
Index: builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.270
diff -c -3 -p -r1.270 builtins.c
*** builtins.c	6 Jan 2004 16:51:08 -0000	1.270
--- builtins.c	13 Jan 2004 00:12:13 -0000
*************** std_expand_builtin_va_arg (tree valist, 
*** 3990,3999 ****
--- 3990,4017 ----
    tree align, alignm1;
    tree rounded_size;
    rtx addr;
+   HOST_WIDE_INT boundary;
  
    /* Compute the rounded size of the type.  */
    align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
    alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
+   boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
+   if (boundary > PARM_BOUNDARY)
+     {
+       if (!PAD_VARARGS_DOWN)
+ 	{
+ 	  t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
+ 		     build (PLUS_EXPR, TREE_TYPE (valist), valist,
+ 			    build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
+ 	  TREE_SIDE_EFFECTS (t) = 1;
+ 	  expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ 	}
+       t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
+ 		 build (BIT_AND_EXPR, TREE_TYPE (valist), valist,
+ 			build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
+       TREE_SIDE_EFFECTS (t) = 1;
+       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+     }
    if (type == error_mark_node
        || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
        || TREE_OVERFLOW (type_size))
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.633
diff -c -3 -p -r1.633 i386.c
*** config/i386/i386.c	9 Jan 2004 02:31:40 -0000	1.633
--- config/i386/i386.c	13 Jan 2004 00:12:52 -0000
*************** init_cumulative_args (CUMULATIVE_ARGS *c
*** 1839,1844 ****
--- 1839,1846 ----
      cum->nregs = ix86_regparm;
    cum->sse_nregs = SSE_REGPARM_MAX;
    cum->mmx_nregs = MMX_REGPARM_MAX;
+   cum->warn_sse = true;
+   cum->warn_mmx = true;
    cum->maybe_vaarg = false;
  
    /* Use ecx and edx registers if function has fastcall attribute */
*************** init_cumulative_args (CUMULATIVE_ARGS *c
*** 1857,1863 ****
       are no variable arguments.  If there are variable arguments, then
       we won't pass anything in registers */
  
!   if (cum->nregs)
      {
        for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
  	   param != 0; param = next_param)
--- 1859,1865 ----
       are no variable arguments.  If there are variable arguments, then
       we won't pass anything in registers */
  
!   if (cum->nregs || !TARGET_MMX || !TARGET_SSE)
      {
        for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
  	   param != 0; param = next_param)
*************** init_cumulative_args (CUMULATIVE_ARGS *c
*** 1868,1873 ****
--- 1870,1879 ----
  	      if (!TARGET_64BIT)
  		{
  		  cum->nregs = 0;
+ 		  cum->sse_nregs = 0;
+ 		  cum->mmx_nregs = 0;
+ 		  cum->warn_sse = 0;
+ 		  cum->warn_mmx = 0;
  		  cum->fastcall = 0;
  		}
  	      cum->maybe_vaarg = true;
*************** function_arg (CUMULATIVE_ARGS *cum,	/* c
*** 2581,2587 ****
        case V2DFmode:
  	if (!type || !AGGREGATE_TYPE_P (type))
  	  {
! 	    if (!TARGET_SSE && !warnedmmx)
  	      {
  		warnedsse = true;
  		warning ("SSE vector argument without SSE enabled "
--- 2587,2593 ----
        case V2DFmode:
  	if (!type || !AGGREGATE_TYPE_P (type))
  	  {
! 	    if (!TARGET_SSE && !warnedmmx && cum->warn_sse)
  	      {
  		warnedsse = true;
  		warning ("SSE vector argument without SSE enabled "
*************** function_arg (CUMULATIVE_ARGS *cum,	/* c
*** 2597,2603 ****
        case V2SFmode:
  	if (!type || !AGGREGATE_TYPE_P (type))
  	  {
! 	    if (!TARGET_MMX && !warnedmmx)
  	      {
  		warnedmmx = true;
  		warning ("MMX vector argument without MMX enabled "
--- 2603,2609 ----
        case V2SFmode:
  	if (!type || !AGGREGATE_TYPE_P (type))
  	  {
! 	    if (!TARGET_MMX && !warnedmmx && cum->warn_mmx)
  	      {
  		warnedmmx = true;
  		warning ("MMX vector argument without MMX enabled "
Index: config/i386/i386.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.h,v
retrieving revision 1.367
diff -c -3 -p -r1.367 i386.h
*** config/i386/i386.h	6 Jan 2004 10:49:56 -0000	1.367
--- config/i386/i386.h	13 Jan 2004 00:13:03 -0000
*************** typedef struct ix86_args {
*** 1743,1748 ****
--- 1743,1750 ----
    int fastcall;		/* fastcall calling convention is used */
    int sse_words;		/* # sse words passed so far */
    int sse_nregs;		/* # sse registers available for passing */
+   int warn_sse;			/* True when we want to warn about SSE ABI.  */
+   int warn_mmx;			/* True when we want to warn about MMX ABI.  */
    int sse_regno;		/* next available sse register number */
    int mmx_words;		/* # mmx words passed so far */
    int mmx_nregs;		/* # mmx registers available for passing */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]