aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Glisse <marc.glisse@inria.fr>2012-09-10 20:48:34 +0200
committerMarc Glisse <glisse@gcc.gnu.org>2012-09-10 18:48:34 +0000
commit881a9dcdef0b5350bb535faa59488cfc9d7a1eeb (patch)
tree90f9e4ccf5c5a6dac2bb628c6b5c6b5aa196ccc0
parent965c17988d6d4d0e8e943e087698bff6f9318a4a (diff)
downloadgcc-881a9dcdef0b5350bb535faa59488cfc9d7a1eeb.zip
gcc-881a9dcdef0b5350bb535faa59488cfc9d7a1eeb.tar.gz
gcc-881a9dcdef0b5350bb535faa59488cfc9d7a1eeb.tar.bz2
tree-ssa-forwprop.c (simplify_bitfield_ref): New function.
2012-09-10 Marc Glisse <marc.glisse@inria.fr> gcc/ * tree-ssa-forwprop.c (simplify_bitfield_ref): New function. (ssa_forward_propagate_and_combine): Call it. gcc/testsuite/ * gcc.dg/tree-ssa/forwprop-21.c: New testcase. From-SVN: r191158
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c13
-rw-r--r--gcc/tree-ssa-forwprop.c74
4 files changed, 96 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3abb393..281540f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2012-09-10 Marc Glisse <marc.glisse@inria.fr>
+
+ * tree-ssa-forwprop.c (simplify_bitfield_ref): New function.
+ (ssa_forward_propagate_and_combine): Call it.
+
2012-09-10 Steve Ellcey <sellcey@mips.com>
* config.gcc: Add mips*-mti-linux* target
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b8f4c39..dc35774 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2012-09-10 Marc Glisse <marc.glisse@inria.fr>
+
+ * gcc.dg/tree-ssa/forwprop-21.c: New testcase.
+
2012-09-10 Aldy Hernandez <aldyh@redhat.com>
* gcc.dg/tm/reg-promotion.c: Modify dump message check.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c
new file mode 100644
index 0000000..4859fa8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+typedef int v4si __attribute__ ((vector_size (4 * sizeof(int))));
+
+int
+test (v4si *x, v4si *y)
+{
+ v4si m = { 2, 3, 6, 5 };
+ v4si z = __builtin_shuffle (*x, *y, m);
+ return z[2];
+}
+/* { dg-final { scan-tree-dump-not "VEC_PERM_EXPR" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 72217ec..5692e21 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2574,6 +2574,78 @@ combine_conversions (gimple_stmt_iterator *gsi)
return 0;
}
+/* Combine an element access with a shuffle. Returns true if there were
+ any changes made, else it returns false. */
+
+static bool
+simplify_bitfield_ref (gimple_stmt_iterator *gsi)
+{
+ gimple stmt = gsi_stmt (*gsi);
+ gimple def_stmt;
+ tree op, op0, op1, op2;
+ tree elem_type;
+ unsigned idx, n, size;
+ enum tree_code code;
+
+ op = gimple_assign_rhs1 (stmt);
+ gcc_checking_assert (TREE_CODE (op) == BIT_FIELD_REF);
+
+ op0 = TREE_OPERAND (op, 0);
+ if (TREE_CODE (op0) != SSA_NAME
+ || TREE_CODE (TREE_TYPE (op0)) != VECTOR_TYPE)
+ return false;
+
+ elem_type = TREE_TYPE (TREE_TYPE (op0));
+ if (TREE_TYPE (op) != elem_type)
+ return false;
+
+ size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
+ op1 = TREE_OPERAND (op, 1);
+ n = TREE_INT_CST_LOW (op1) / size;
+ if (n != 1)
+ return false;
+
+ def_stmt = SSA_NAME_DEF_STMT (op0);
+ if (!def_stmt || !is_gimple_assign (def_stmt)
+ || !can_propagate_from (def_stmt))
+ return false;
+
+ op2 = TREE_OPERAND (op, 2);
+ idx = TREE_INT_CST_LOW (op2) / size;
+
+ code = gimple_assign_rhs_code (def_stmt);
+
+ if (code == VEC_PERM_EXPR)
+ {
+ tree p, m, index, tem;
+ unsigned nelts;
+ m = gimple_assign_rhs3 (def_stmt);
+ if (TREE_CODE (m) != VECTOR_CST)
+ return false;
+ nelts = VECTOR_CST_NELTS (m);
+ idx = TREE_INT_CST_LOW (VECTOR_CST_ELT (m, idx));
+ idx %= 2 * nelts;
+ if (idx < nelts)
+ {
+ p = gimple_assign_rhs1 (def_stmt);
+ }
+ else
+ {
+ p = gimple_assign_rhs2 (def_stmt);
+ idx -= nelts;
+ }
+ index = build_int_cst (TREE_TYPE (TREE_TYPE (m)), idx * size);
+ tem = build3 (BIT_FIELD_REF, TREE_TYPE (op),
+ unshare_expr (p), op1, index);
+ gimple_assign_set_rhs1 (stmt, tem);
+ fold_stmt (gsi);
+ update_stmt (gsi_stmt (*gsi));
+ return true;
+ }
+
+ return false;
+}
+
/* Determine whether applying the 2 permutations (mask1 then mask2)
gives back one of the input. */
@@ -2891,6 +2963,8 @@ ssa_forward_propagate_and_combine (void)
cfg_changed = true;
changed = did_something != 0;
}
+ else if (code == BIT_FIELD_REF)
+ changed = simplify_bitfield_ref (&gsi);
break;
}