This fixes the original request in PR77399, better handling of
typedef int v4si __attribute__((vector_size(16)));
typedef float v4sf __attribute__((vector_size(16)));
v4sf vec_cast(v4si f)
{
return (v4sf){f[0], f[1], f[2], f[3]};
}
which nicely fits into the existing simplify_vector_constructor code.
Bootstrap / regtest pending on x86_64-unknown-linux-gnu.
Richard.
2016-09-28 Richard Biener <[email protected]>
PR tree-optimization/77399
* tree-ssa-forwprop.c (simplify_vector_constructor): Handle
float <-> int conversions.
* gcc.dg/tree-ssa/forwprop-35.c: New testcase.
Index: gcc/tree-ssa-forwprop.c
===================================================================
*** gcc/tree-ssa-forwprop.c (revision 240565)
--- gcc/tree-ssa-forwprop.c (working copy)
*************** simplify_vector_constructor (gimple_stmt
*** 1953,1959 ****
gimple *def_stmt;
tree op, op2, orig, type, elem_type;
unsigned elem_size, nelts, i;
! enum tree_code code;
constructor_elt *elt;
unsigned char *sel;
bool maybe_ident;
--- 1953,1959 ----
gimple *def_stmt;
tree op, op2, orig, type, elem_type;
unsigned elem_size, nelts, i;
! enum tree_code code, conv_code;
constructor_elt *elt;
unsigned char *sel;
bool maybe_ident;
*************** simplify_vector_constructor (gimple_stmt
*** 1970,1975 ****
--- 1970,1976 ----
sel = XALLOCAVEC (unsigned char, nelts);
orig = NULL;
+ conv_code = ERROR_MARK;
maybe_ident = true;
FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (op), i, elt)
{
*************** simplify_vector_constructor (gimple_stmt
*** 1984,1989 ****
--- 1985,2008 ----
if (!def_stmt)
return false;
code = gimple_assign_rhs_code (def_stmt);
+ if (code == FLOAT_EXPR
+ || code == FIX_TRUNC_EXPR)
+ {
+ op1 = gimple_assign_rhs1 (def_stmt);
+ if (conv_code == ERROR_MARK)
+ {
+ if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (elt->value)))
+ != GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (op1))))
+ return false;
+ conv_code = code;
+ }
+ else if (conv_code != code)
+ return false;
+ if (TREE_CODE (op1) != SSA_NAME)
+ return false;
+ def_stmt = SSA_NAME_DEF_STMT (op1);
+ code = gimple_assign_rhs_code (def_stmt);
+ }
if (code != BIT_FIELD_REF)
return false;
op1 = gimple_assign_rhs1 (def_stmt);
*************** simplify_vector_constructor (gimple_stmt
*** 1997,2003 ****
{
if (TREE_CODE (ref) != SSA_NAME)
return false;
! if (!useless_type_conversion_p (type, TREE_TYPE (ref)))
return false;
orig = ref;
}
--- 2016,2024 ----
{
if (TREE_CODE (ref) != SSA_NAME)
return false;
! if (! VECTOR_TYPE_P (TREE_TYPE (ref))
! || ! useless_type_conversion_p (TREE_TYPE (op1),
! TREE_TYPE (TREE_TYPE (ref))))
return false;
orig = ref;
}
*************** simplify_vector_constructor (gimple_stmt
*** 2010,2016 ****
return false;
if (maybe_ident)
! gimple_assign_set_rhs_from_tree (gsi, orig);
else
{
tree mask_type, *mask_elts;
--- 2031,2043 ----
return false;
if (maybe_ident)
! {
! if (conv_code == ERROR_MARK)
! gimple_assign_set_rhs_from_tree (gsi, orig);
! else
! gimple_assign_set_rhs_with_ops (gsi, conv_code, orig,
! NULL_TREE, NULL_TREE);
! }
else
{
tree mask_type, *mask_elts;
*************** simplify_vector_constructor (gimple_stmt
*** 2028,2034 ****
for (i = 0; i < nelts; i++)
mask_elts[i] = build_int_cst (TREE_TYPE (mask_type), sel[i]);
op2 = build_vector (mask_type, mask_elts);
! gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig, orig, op2);
}
update_stmt (gsi_stmt (*gsi));
return true;
--- 2055,2072 ----
for (i = 0; i < nelts; i++)
mask_elts[i] = build_int_cst (TREE_TYPE (mask_type), sel[i]);
op2 = build_vector (mask_type, mask_elts);
! if (conv_code == ERROR_MARK)
! gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig, orig, op2);
! else
! {
! gimple *perm
! = gimple_build_assign (make_ssa_name (TREE_TYPE (orig)),
! VEC_PERM_EXPR, orig, orig, op2);
! orig = gimple_assign_lhs (perm);
! gsi_insert_before (gsi, perm, GSI_SAME_STMT);
! gimple_assign_set_rhs_with_ops (gsi, conv_code, orig,
! NULL_TREE, NULL_TREE);
! }
}
update_stmt (gsi_stmt (*gsi));
return true;
Index: gcc/testsuite/gcc.dg/tree-ssa/forwprop-35.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/forwprop-35.c (revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/forwprop-35.c (working copy)
***************
*** 0 ****
--- 1,18 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-cddce1" } */
+
+ typedef int v4si __attribute__((vector_size(16)));
+ typedef float v4sf __attribute__((vector_size(16)));
+
+ v4sf vec_cast(v4si f)
+ {
+ return (v4sf){f[0], f[1], f[2], f[3]};
+ }
+
+ v4sf vec_cast_perm(v4si f)
+ {
+ return (v4sf){f[1], f[1], f[2], f[3]};
+ }
+
+ /* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 1 "cddce1" } } */
+ /* { dg-final { scan-tree-dump-times "\\\(v4sf\\\) " 2 "cddce1" } } */