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]

[PATCH] Fix PR target-i386 / 23289


This fixes a missed tailcall opportunity introduced by the patch
to fix PR22347.  We can tailcall from/to a function returning void
to one returning in a (non-stack) register.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Ok for mainline?

Thanks,
Richard.

:ADDPATCH i386:

2005-08-09  Richard Guenther  <rguenther@suse.de>

	PR target/23289
	* config/i386/i386.c (ix86_function_ok_for_sibcall): Handle
	cases where we call to/from functions returning void.

	* gcc.target/i386/tailcall-1.c: New testcase.


Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.851
diff -c -3 -p -r1.851 i386.c
*** config/i386/i386.c	8 Aug 2005 16:29:49 -0000	1.851
--- config/i386/i386.c	9 Aug 2005 09:06:50 -0000
*************** ix86_function_ok_for_sibcall (tree decl,
*** 1929,1939 ****
       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.  This is also the place we notice
!      differences in the return value ABI.  */
    a = ix86_function_value (TREE_TYPE (exp), func, false);
    b = ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
  			   cfun->decl, false);
!   if (! rtx_equal_p (a, b))
      return false;
  
    /* If this call is indirect, we'll need to be able to use a call-clobbered
--- 1929,1945 ----
       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.  This is also the place we notice
!      differences in the return value ABI.  Note that it is ok for one
!      of the functions to have void return type as long as the return
!      value of the other is passed in a register.  */
    a = ix86_function_value (TREE_TYPE (exp), func, false);
    b = ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)),
  			   cfun->decl, false);
!   if (!((TREE_TYPE (exp) == void_type_node
!          || TREE_TYPE (DECL_RESULT (cfun->decl)) == void_type_node)
!         && ((REG_P (a) && !STACK_REG_P (a))
! 	    || (REG_P (b) && !STACK_REG_P (b))))
!       && !rtx_equal_p (a, b))
      return false;
  
    /* If this call is indirect, we'll need to be able to use a call-clobbered



/* { dg-do compile } */
/* { dg-options "-O2" } */

typedef unsigned int Cardinal;
typedef char *String;
typedef struct _WidgetRec *Widget;

typedef union _XEvent {
        int type;
 long pad[24];
} XEvent;


extern int SendMousePosition (Widget w, XEvent* event);


void
HandleIgnore(Widget w,
      XEvent * event,
      String * params ,
      Cardinal *param_count )
{

    (void) SendMousePosition(w, event);
}

/* { dg-final { scan-assembler "jmp" } } */


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