diff options
author | Richard Biener <rguenther@suse.de> | 2016-09-30 07:06:16 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2016-09-30 07:06:16 +0000 |
commit | f334c828feae86ecdcc6a8f0b35425147057539f (patch) | |
tree | 3a47b0fd6b35fd56851119c0b5aa8db1773b406a /gcc | |
parent | 76e3ec9ca98e93fa1de2806b4de46de513a2da7d (diff) | |
download | gcc-f334c828feae86ecdcc6a8f0b35425147057539f.zip gcc-f334c828feae86ecdcc6a8f0b35425147057539f.tar.gz gcc-f334c828feae86ecdcc6a8f0b35425147057539f.tar.bz2 |
re PR tree-optimization/77399 (Poor code generation for vector casts and loads)
2016-09-30 Richard Biener <rguenther@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.
From-SVN: r240646
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/forwprop-35.c | 18 | ||||
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 53 |
4 files changed, 78 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6892a5a..d0a4199 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-09-30 Richard Biener <rguenther@suse.de> + + PR tree-optimization/77399 + * tree-ssa-forwprop.c (simplify_vector_constructor): Handle + float <-> int conversions. + 2016-09-30 Alan Modra <amodra@gmail.com> * config/rs6000/rs6000.c (rs6000_opt_vars): Revert last change. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b5106656..7ea9961 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-09-30 Richard Biener <rguenther@suse.de> + + PR tree-optimization/77399 + * gcc.dg/tree-ssa/forwprop-35.c: New testcase. + 2016-09-29 Sandra Loosemore <sandra@codesourcery.com> * c-c++-common/pr27336.c: Make dependency on diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-35.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-35.c new file mode 100644 index 0000000..24a1ad9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-35.c @@ -0,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" } } */ diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 9cf2768..cd066ef 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -1953,7 +1953,7 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) gimple *def_stmt; tree op, op2, orig, type, elem_type; unsigned elem_size, nelts, i; - enum tree_code code; + enum tree_code code, conv_code; constructor_elt *elt; unsigned char *sel; bool maybe_ident; @@ -1970,6 +1970,7 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) sel = XALLOCAVEC (unsigned char, nelts); orig = NULL; + conv_code = ERROR_MARK; maybe_ident = true; FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (op), i, elt) { @@ -1984,6 +1985,26 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) 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); @@ -1997,7 +2018,9 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) { if (TREE_CODE (ref) != SSA_NAME) return false; - if (!useless_type_conversion_p (type, TREE_TYPE (ref))) + if (! VECTOR_TYPE_P (TREE_TYPE (ref)) + || ! useless_type_conversion_p (TREE_TYPE (op1), + TREE_TYPE (TREE_TYPE (ref)))) return false; orig = ref; } @@ -2009,8 +2032,19 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) 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) - gimple_assign_set_rhs_from_tree (gsi, orig); + { + 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; @@ -2028,7 +2062,18 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi) 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); + 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; |