On Wed, 28 Sep 2016, Richard Biener wrote: > > 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.
This is the variant I applied (with some fixed issues). Bootstrapped and tested on x86_64-unknown-linux-gnu. Richard. 2016-09-30 Richard Biener <rguent...@suse.de> 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 240612) --- 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,2010 ---- 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); + if (! is_gimple_assign (def_stmt)) + return false; + 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; } --- 2018,2026 ---- { 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 *** 2009,2016 **** if (i < nelts) return false; if (maybe_ident) ! gimple_assign_set_rhs_from_tree (gsi, orig); else { tree mask_type, *mask_elts; --- 2032,2050 ---- if (i < nelts) return false; + if (! VECTOR_TYPE_P (TREE_TYPE (orig)) + || (TYPE_VECTOR_SUBPARTS (type) + != TYPE_VECTOR_SUBPARTS (TREE_TYPE (orig)))) + 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; --- 2062,2079 ---- 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" } } */