aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-09-30 07:06:16 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-09-30 07:06:16 +0000
commitf334c828feae86ecdcc6a8f0b35425147057539f (patch)
tree3a47b0fd6b35fd56851119c0b5aa8db1773b406a /gcc
parent76e3ec9ca98e93fa1de2806b4de46de513a2da7d (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/forwprop-35.c18
-rw-r--r--gcc/tree-ssa-forwprop.c53
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;