[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