[PATCH][4.6] Fix builtin_conversion target-hook for AVX

Richard Guenther rguenther@suse.de
Wed Mar 3 13:11:00 GMT 2010


With different vector sizes in AVX the builtin_conversion signature is
not enough to distinguish all handled cases.  Fixed with the following,
queued for 4.6.

Ok?

Thanks,
Richard.

2010-03-03  Richard Guenther  <rguenther@suse.de>

	* target.h (builtin_conversion): Pass in input and output types.
	* targhooks.c (default_builtin_vectorized_conversion): Adjust.
	* targhooks.h (default_builtin_vectorized_conversion): Likewise.
	* tree-vect-stmts.c (vectorizable_conversion): Adjust.

	* config/i386/i386.c (ix86_vectorize_builtin_conversion): Adjust.
	Handle AVX modes.
	* config/rs6000/rs6000.c (rs6000_builtin_conversion): Adjust.

Index: trunk/gcc/config/i386/i386.c
===================================================================
*** trunk.orig/gcc/config/i386/i386.c	2010-03-01 17:39:01.000000000 +0100
--- trunk/gcc/config/i386/i386.c	2010-03-01 17:39:05.000000000 +0100
*************** ix86_veclibabi_acml (enum built_in_funct
*** 24573,24615 ****
  
  
  /* Returns a decl of a function that implements conversion of an integer vector
!    into a floating-point vector, or vice-versa. TYPE is the type of the integer
!    side of the conversion.
     Return NULL_TREE if it is not available.  */
  
  static tree
! ix86_vectorize_builtin_conversion (unsigned int code, tree type)
  {
!   if (! (TARGET_SSE2 && TREE_CODE (type) == VECTOR_TYPE))
      return NULL_TREE;
  
    switch (code)
      {
      case FLOAT_EXPR:
!       switch (TYPE_MODE (type))
  	{
  	case V4SImode:
! 	  return TYPE_UNSIGNED (type)
! 	    ? ix86_builtins[IX86_BUILTIN_CVTUDQ2PS]
! 	    : ix86_builtins[IX86_BUILTIN_CVTDQ2PS];
  	default:
  	  return NULL_TREE;
  	}
  
      case FIX_TRUNC_EXPR:
!       switch (TYPE_MODE (type))
  	{
  	case V4SImode:
! 	  return TYPE_UNSIGNED (type)
! 	    ? NULL_TREE
! 	    : ix86_builtins[IX86_BUILTIN_CVTTPS2DQ];
  	default:
  	  return NULL_TREE;
  	}
      default:
        return NULL_TREE;
- 
      }
  }
  
  /* Returns a code for a target-specific builtin that implements
--- 24573,24664 ----
  
  
  /* Returns a decl of a function that implements conversion of an integer vector
!    into a floating-point vector, or vice-versa.  DEST_TYPE and SRC_TYPE
!    are the types involved when converting according to CODE.
     Return NULL_TREE if it is not available.  */
  
  static tree
! ix86_vectorize_builtin_conversion (unsigned int code,
! 				   tree dest_type, tree src_type)
  {
!   if (! TARGET_SSE2)
      return NULL_TREE;
  
    switch (code)
      {
      case FLOAT_EXPR:
!       switch (TYPE_MODE (src_type))
  	{
  	case V4SImode:
! 	  switch (TYPE_MODE (dest_type))
! 	    {
! 	    case V4SFmode:
! 	      return (TYPE_UNSIGNED (src_type)
! 		      ? ix86_builtins[IX86_BUILTIN_CVTUDQ2PS]
! 		      : ix86_builtins[IX86_BUILTIN_CVTDQ2PS]);
! 	    case V4DFmode:
! 	      return (TYPE_UNSIGNED (src_type)
! 		      ? NULL_TREE
! 		      : ix86_builtins[IX86_BUILTIN_CVTDQ2PD256]);
! 	    default:
! 	      return NULL_TREE;
! 	    }
! 	  break;
! 	case V8SImode:
! 	  switch (TYPE_MODE (dest_type))
! 	    {
! 	    case V8SFmode:
! 	      return (TYPE_UNSIGNED (src_type)
! 		      ? NULL_TREE
! 		      : ix86_builtins[IX86_BUILTIN_CVTDQ2PS]);
! 	    default:
! 	      return NULL_TREE;
! 	    }
! 	  break;
  	default:
  	  return NULL_TREE;
  	}
  
      case FIX_TRUNC_EXPR:
!       switch (TYPE_MODE (dest_type))
  	{
  	case V4SImode:
! 	  switch (TYPE_MODE (src_type))
! 	    {
! 	    case V4SFmode:
! 	      return (TYPE_UNSIGNED (dest_type)
! 		      ? NULL_TREE
! 		      : ix86_builtins[IX86_BUILTIN_CVTTPS2DQ]);
! 	    case V4DFmode:
! 	      return (TYPE_UNSIGNED (dest_type)
! 		      ? NULL_TREE
! 		      : ix86_builtins[IX86_BUILTIN_CVTTPD2DQ256]);
! 	    default:
! 	      return NULL_TREE;
! 	    }
! 	  break;
! 
! 	case V8SImode:
! 	  switch (TYPE_MODE (src_type))
! 	    {
! 	    case V8SFmode:
! 	      return (TYPE_UNSIGNED (dest_type)
! 		      ? NULL_TREE
! 		      : ix86_builtins[IX86_BUILTIN_CVTTPS2DQ256]);
! 	    default:
! 	      return NULL_TREE;
! 	    }
! 	  break;
! 
  	default:
  	  return NULL_TREE;
  	}
+ 
      default:
        return NULL_TREE;
      }
+ 
+   return NULL_TREE;
  }
  
  /* Returns a code for a target-specific builtin that implements
Index: trunk/gcc/target.h
===================================================================
*** trunk.orig/gcc/target.h	2010-03-01 17:39:01.000000000 +0100
--- trunk/gcc/target.h	2010-03-01 17:39:05.000000000 +0100
*************** struct gcc_target
*** 469,477 ****
         function, or NULL_TREE if not available.  */
      tree (* builtin_vectorized_function) (unsigned, tree, tree);
  
!     /* Returns a code for builtin that realizes vectorized version of
!        conversion, or NULL_TREE if not available.  */
!     tree (* builtin_conversion) (unsigned, tree);
  
      /* Target builtin that implements vector widening multiplication.
         builtin_mul_widen_eve computes the element-by-element products
--- 469,477 ----
         function, or NULL_TREE if not available.  */
      tree (* builtin_vectorized_function) (unsigned, tree, tree);
  
!     /* Returns a function declaration for a builtin that realizes the
!        vector conversion, or NULL_TREE if not available.  */
!     tree (* builtin_conversion) (unsigned, tree, tree);
  
      /* Target builtin that implements vector widening multiplication.
         builtin_mul_widen_eve computes the element-by-element products
Index: trunk/gcc/targhooks.c
===================================================================
*** trunk.orig/gcc/targhooks.c	2010-03-01 17:39:01.000000000 +0100
--- trunk/gcc/targhooks.c	2010-03-01 17:39:05.000000000 +0100
*************** default_builtin_vectorized_function (uns
*** 430,436 ****
  
  tree
  default_builtin_vectorized_conversion (unsigned int code ATTRIBUTE_UNUSED,
! 				       tree type ATTRIBUTE_UNUSED)
  {
    return NULL_TREE;
  }
--- 430,437 ----
  
  tree
  default_builtin_vectorized_conversion (unsigned int code ATTRIBUTE_UNUSED,
! 				       tree dest_type ATTRIBUTE_UNUSED,
! 				       tree src_type ATTRIBUTE_UNUSED)
  {
    return NULL_TREE;
  }
Index: trunk/gcc/targhooks.h
===================================================================
*** trunk.orig/gcc/targhooks.h	2010-03-01 17:39:01.000000000 +0100
--- trunk/gcc/targhooks.h	2010-03-01 17:39:05.000000000 +0100
*************** extern const char * default_invalid_with
*** 72,78 ****
  
  extern tree default_builtin_vectorized_function (unsigned int, tree, tree);
  
! extern tree default_builtin_vectorized_conversion (unsigned int, tree);
  
  extern tree default_builtin_reciprocal (unsigned int, bool, bool);
  
--- 72,78 ----
  
  extern tree default_builtin_vectorized_function (unsigned int, tree, tree);
  
! extern tree default_builtin_vectorized_conversion (unsigned int, tree, tree);
  
  extern tree default_builtin_reciprocal (unsigned int, bool, bool);
  
Index: trunk/gcc/config/rs6000/rs6000.c
===================================================================
*** trunk.orig/gcc/config/rs6000/rs6000.c	2010-03-01 17:39:01.000000000 +0100
--- trunk/gcc/config/rs6000/rs6000.c	2010-03-01 17:39:05.000000000 +0100
*************** static tree rs6000_builtin_reciprocal (u
*** 990,996 ****
  static tree rs6000_builtin_mask_for_load (void);
  static tree rs6000_builtin_mul_widen_even (tree);
  static tree rs6000_builtin_mul_widen_odd (tree);
! static tree rs6000_builtin_conversion (unsigned int, tree);
  static tree rs6000_builtin_vec_perm (tree, tree *);
  static bool rs6000_builtin_support_vector_misalignment (enum
  							machine_mode,
--- 990,996 ----
  static tree rs6000_builtin_mask_for_load (void);
  static tree rs6000_builtin_mul_widen_even (tree);
  static tree rs6000_builtin_mul_widen_odd (tree);
! static tree rs6000_builtin_conversion (unsigned int, tree, tree);
  static tree rs6000_builtin_vec_perm (tree, tree *);
  static bool rs6000_builtin_support_vector_misalignment (enum
  							machine_mode,
*************** rs6000_builtin_mask_for_load (void)
*** 2886,2909 ****
  
  /* Implement targetm.vectorize.builtin_conversion.
     Returns a decl of a function that implements conversion of an integer vector
!    into a floating-point vector, or vice-versa. TYPE is the type of the integer
!    side of the conversion.
     Return NULL_TREE if it is not available.  */
  static tree
! rs6000_builtin_conversion (unsigned int tcode, tree type)
  {
    enum tree_code code = (enum tree_code) tcode;
  
    switch (code)
      {
      case FIX_TRUNC_EXPR:
!       switch (TYPE_MODE (type))
  	{
  	case V2DImode:
  	  if (!VECTOR_UNIT_VSX_P (V2DFmode))
  	    return NULL_TREE;
  
! 	  return TYPE_UNSIGNED (type)
  	    ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
  	    : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
  
--- 2886,2909 ----
  
  /* Implement targetm.vectorize.builtin_conversion.
     Returns a decl of a function that implements conversion of an integer vector
!    into a floating-point vector, or vice-versa.  DEST_TYPE is the
!    destination type and SRC_TYPE the source type of the conversion.
     Return NULL_TREE if it is not available.  */
  static tree
! rs6000_builtin_conversion (unsigned int tcode, tree dest_type, tree src_type)
  {
    enum tree_code code = (enum tree_code) tcode;
  
    switch (code)
      {
      case FIX_TRUNC_EXPR:
!       switch (TYPE_MODE (dest_type))
  	{
  	case V2DImode:
  	  if (!VECTOR_UNIT_VSX_P (V2DFmode))
  	    return NULL_TREE;
  
! 	  return TYPE_UNSIGNED (dest_type)
  	    ? rs6000_builtin_decls[VSX_BUILTIN_XVCVDPUXDS_UNS]
  	    : rs6000_builtin_decls[VSX_BUILTIN_XVCVDPSXDS];
  
*************** rs6000_builtin_conversion (unsigned int
*** 2911,2917 ****
  	  if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
  	    return NULL_TREE;
  
! 	  return TYPE_UNSIGNED (type)
  	    ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
  	    : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
  
--- 2911,2917 ----
  	  if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
  	    return NULL_TREE;
  
! 	  return TYPE_UNSIGNED (dest_type)
  	    ? rs6000_builtin_decls[VECTOR_BUILTIN_FIXUNS_V4SF_V4SI]
  	    : rs6000_builtin_decls[VECTOR_BUILTIN_FIX_V4SF_V4SI];
  
*************** rs6000_builtin_conversion (unsigned int
*** 2920,2932 ****
  	}
  
      case FLOAT_EXPR:
!       switch (TYPE_MODE (type))
  	{
  	case V2DImode:
  	  if (!VECTOR_UNIT_VSX_P (V2DFmode))
  	    return NULL_TREE;
  
! 	  return TYPE_UNSIGNED (type)
  	    ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
  	    : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
  
--- 2920,2932 ----
  	}
  
      case FLOAT_EXPR:
!       switch (TYPE_MODE (src_type))
  	{
  	case V2DImode:
  	  if (!VECTOR_UNIT_VSX_P (V2DFmode))
  	    return NULL_TREE;
  
! 	  return TYPE_UNSIGNED (src_type)
  	    ? rs6000_builtin_decls[VSX_BUILTIN_XVCVUXDDP]
  	    : rs6000_builtin_decls[VSX_BUILTIN_XVCVSXDDP];
  
*************** rs6000_builtin_conversion (unsigned int
*** 2934,2940 ****
  	  if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
  	    return NULL_TREE;
  
! 	  return TYPE_UNSIGNED (type)
  	    ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
  	    : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
  
--- 2934,2940 ----
  	  if (VECTOR_UNIT_NONE_P (V4SImode) || VECTOR_UNIT_NONE_P (V4SFmode))
  	    return NULL_TREE;
  
! 	  return TYPE_UNSIGNED (src_type)
  	    ? rs6000_builtin_decls[VECTOR_BUILTIN_UNSFLOAT_V4SI_V4SF]
  	    : rs6000_builtin_decls[VECTOR_BUILTIN_FLOAT_V4SI_V4SF];
  
Index: trunk/gcc/tree-vect-stmts.c
===================================================================
*** trunk.orig/gcc/tree-vect-stmts.c	2010-03-01 17:31:52.000000000 +0100
--- trunk/gcc/tree-vect-stmts.c	2010-03-01 17:44:32.000000000 +0100
*************** vectorizable_conversion (gimple stmt, gi
*** 1640,1646 ****
  
    /* Supportable by target?  */
    if ((modifier == NONE
!        && !targetm.vectorize.builtin_conversion (code, integral_type))
        || (modifier == WIDEN
  	  && !supportable_widening_operation (code, stmt,
  					      vectype_out, vectype_in,
--- 1640,1646 ----
  
    /* Supportable by target?  */
    if ((modifier == NONE
!        && !targetm.vectorize.builtin_conversion (code, vectype_out, vectype_in))
        || (modifier == WIDEN
  	  && !supportable_widening_operation (code, stmt,
  					      vectype_out, vectype_in,
*************** vectorizable_conversion (gimple stmt, gi
*** 1691,1697 ****
  	    vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, NULL);
  
  	  builtin_decl =
! 	    targetm.vectorize.builtin_conversion (code, integral_type);
  	  for (i = 0; VEC_iterate (tree, vec_oprnds0, i, vop0); i++)
  	    {
  	      /* Arguments are ready. create the new vector stmt.  */
--- 1691,1698 ----
  	    vect_get_vec_defs_for_stmt_copy (dt, &vec_oprnds0, NULL);
  
  	  builtin_decl =
! 	    targetm.vectorize.builtin_conversion (code,
! 						  vectype_out, vectype_in);
  	  for (i = 0; VEC_iterate (tree, vec_oprnds0, i, vop0); i++)
  	    {
  	      /* Arguments are ready. create the new vector stmt.  */



More information about the Gcc-patches mailing list