rs6000.c (map_to_integral_tree_type): New helper function.

[gcc]

2018-10-09  Will Schmidt <will_schmidt@vnet.ibm.com>

	* config/rs6000/rs6000.c (map_to_integral_tree_type): New helper
	function.
	(fold_mergeeo_helper): New helper function.
	(rs6000_gimple_fold_builtin): Add hooks for vec_mergee and vec_mergeo
	intrinsics.  Correct some whitespace indentation issues.

From-SVN: r265063
This commit is contained in:
Will Schmidt 2018-10-11 21:03:30 +00:00 committed by Will Schmidt
parent 5746195cdc
commit ea010af6b4
2 changed files with 186 additions and 123 deletions

View File

@ -1,3 +1,11 @@
2018-10-11 Will Schmidt <will_schmidt@vnet.ibm.com>
* config/rs6000/rs6000.c (map_to_integral_tree_type): New helper
function.
(fold_mergeeo_helper): New helper function.
(rs6000_gimple_fold_builtin): Add hooks for vec_mergee and vec_mergeo
intrinsics. Correct some whitespace indentation issues.
2018-10-11 Wilco Dijkstra <wdijkstr@arm.com> 2018-10-11 Wilco Dijkstra <wdijkstr@arm.com>
PR target/87511 PR target/87511

View File

@ -15238,6 +15238,25 @@ fold_compare_helper (gimple_stmt_iterator *gsi, tree_code code, gimple *stmt)
gsi_replace (gsi, g, true); gsi_replace (gsi, g, true);
} }
/* Helper function to map V2DF and V4SF types to their
integral equivalents (V2DI and V4SI). */
tree map_to_integral_tree_type (tree input_tree_type)
{
if (INTEGRAL_TYPE_P (TREE_TYPE (input_tree_type)))
return input_tree_type;
else
{
if (types_compatible_p (TREE_TYPE (input_tree_type),
TREE_TYPE (V2DF_type_node)))
return V2DI_type_node;
else if (types_compatible_p (TREE_TYPE (input_tree_type),
TREE_TYPE (V4SF_type_node)))
return V4SI_type_node;
else
gcc_unreachable ();
}
}
/* Helper function to handle the vector merge[hl] built-ins. The /* Helper function to handle the vector merge[hl] built-ins. The
implementation difference between h and l versions for this code are in implementation difference between h and l versions for this code are in
the values used when building of the permute vector for high word versus the values used when building of the permute vector for high word versus
@ -15260,19 +15279,7 @@ fold_mergehl_helper (gimple_stmt_iterator *gsi, gimple *stmt, int use_high)
float types, the permute type needs to map to the V2 or V4 type that float types, the permute type needs to map to the V2 or V4 type that
matches size. */ matches size. */
tree permute_type; tree permute_type;
if (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type))) permute_type = map_to_integral_tree_type (lhs_type);
permute_type = lhs_type;
else
{
if (types_compatible_p (TREE_TYPE (lhs_type),
TREE_TYPE (V2DF_type_node)))
permute_type = V2DI_type_node;
else if (types_compatible_p (TREE_TYPE (lhs_type),
TREE_TYPE (V4SF_type_node)))
permute_type = V4SI_type_node;
else
gcc_unreachable ();
}
tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1); tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1);
for (int i = 0; i < midpoint; i++) for (int i = 0; i < midpoint; i++)
@ -15290,6 +15297,40 @@ fold_mergehl_helper (gimple_stmt_iterator *gsi, gimple *stmt, int use_high)
gsi_replace (gsi, g, true); gsi_replace (gsi, g, true);
} }
/* Helper function to handle the vector merge[eo] built-ins. */
static void
fold_mergeeo_helper (gimple_stmt_iterator *gsi, gimple *stmt, int use_odd)
{
tree arg0 = gimple_call_arg (stmt, 0);
tree arg1 = gimple_call_arg (stmt, 1);
tree lhs = gimple_call_lhs (stmt);
tree lhs_type = TREE_TYPE (lhs);
int n_elts = TYPE_VECTOR_SUBPARTS (lhs_type);
/* The permute_type will match the lhs for integral types. For double and
float types, the permute type needs to map to the V2 or V4 type that
matches size. */
tree permute_type;
permute_type = map_to_integral_tree_type (lhs_type);
tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1);
/* Build the permute vector. */
for (int i = 0; i < n_elts / 2; i++)
{
elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
2*i + use_odd));
elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
2*i + use_odd + n_elts));
}
tree permute = elts.build ();
gimple *g = gimple_build_assign (lhs, VEC_PERM_EXPR, arg0, arg1, permute);
gimple_set_location (g, gimple_location (stmt));
gsi_replace (gsi, g, true);
}
/* Fold a machine-dependent built-in in GIMPLE. (For folding into /* Fold a machine-dependent built-in in GIMPLE. (For folding into
a constant, use rs6000_fold_builtin.) */ a constant, use rs6000_fold_builtin.) */
@ -15898,7 +15939,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
case ALTIVEC_BUILTIN_VSPLTISW: case ALTIVEC_BUILTIN_VSPLTISW:
{ {
int size; int size;
if (fn_code == ALTIVEC_BUILTIN_VSPLTISB) if (fn_code == ALTIVEC_BUILTIN_VSPLTISB)
size = 8; size = 8;
else if (fn_code == ALTIVEC_BUILTIN_VSPLTISH) else if (fn_code == ALTIVEC_BUILTIN_VSPLTISH)
@ -15990,6 +16030,21 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
fold_mergehl_helper (gsi, stmt, 0); fold_mergehl_helper (gsi, stmt, 0);
return true; return true;
/* Flavors of vec_mergee. */
case P8V_BUILTIN_VMRGEW_V4SI:
case P8V_BUILTIN_VMRGEW_V2DI:
case P8V_BUILTIN_VMRGEW_V4SF:
case P8V_BUILTIN_VMRGEW_V2DF:
fold_mergeeo_helper (gsi, stmt, 0);
return true;
/* Flavors of vec_mergeo. */
case P8V_BUILTIN_VMRGOW_V4SI:
case P8V_BUILTIN_VMRGOW_V2DI:
case P8V_BUILTIN_VMRGOW_V4SF:
case P8V_BUILTIN_VMRGOW_V2DF:
fold_mergeeo_helper (gsi, stmt, 1);
return true;
/* d = vec_pack (a, b) */ /* d = vec_pack (a, b) */
case P8V_BUILTIN_VPKUDUM: case P8V_BUILTIN_VPKUDUM:
case ALTIVEC_BUILTIN_VPKUHUM: case ALTIVEC_BUILTIN_VPKUHUM: