]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-ssa-forwprop.c (simplify_bitfield_ref): New function.
authorMarc Glisse <marc.glisse@inria.fr>
Mon, 10 Sep 2012 18:48:34 +0000 (20:48 +0200)
committerMarc Glisse <glisse@gcc.gnu.org>
Mon, 10 Sep 2012 18:48:34 +0000 (18:48 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/forwprop-21.c [new file with mode: 0644]
gcc/tree-ssa-forwprop.c

index 3abb393d22aac2a2ee2d283b57a157c3741aa46c..281540f416f175f33f4ca1ba53129e27c092d6fc 100644 (file)
@@ -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
index b8f4c39350d17ad3ee59b3d8857f891735d51915..dc3577401e81d09464ae0a90020259196e3bc85e 100644 (file)
@@ -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 (file)
index 0000000..4859fa8
--- /dev/null
@@ -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" } } */
index 72217ecbdd5e31e5b4e1939fa40536f847807540..5692e21f19d575fd836054fe5b4509057a97bb15 100644 (file)
@@ -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;
              }