re PR tree-optimization/59822 (ice in compute_live_loop_exits with -O3)
authorRichard Biener <rguenther@suse.de>
Wed, 15 Jan 2014 15:13:08 +0000 (15:13 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 15 Jan 2014 15:13:08 +0000 (15:13 +0000)
2014-01-15  Richard Biener  <rguenther@suse.de>

PR tree-optimization/59822
* tree-vect-stmts.c (hoist_defs_of_uses): New function.
(vectorizable_load): Use it to hoist defs of uses of invariant
loads out of the loop.

* g++.dg/torture/pr59822.C: New testcase.

From-SVN: r206630

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr59822.C [new file with mode: 0644]
gcc/tree-vect-stmts.c

index f993e480f7b9173781d57cd925086ee3daab2a07..7ddff7560577640211dba1153f5b3607b544853e 100644 (file)
@@ -1,3 +1,10 @@
+2014-01-15  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/59822
+       * tree-vect-stmts.c (hoist_defs_of_uses): New function.
+       (vectorizable_load): Use it to hoist defs of uses of invariant
+       loads out of the loop.
+
 2014-01-15  Matthew Gretton-Dann  <matthew.gretton-dann@linaro.org>
             Kugan Vivekanandarajah  <kuganv@linaro.org>
 
index dde78783d8d789ed430b5815b941a2f9838eb594..1df5c3a66c268e4b4360c338f9258b8b37f886a6 100644 (file)
@@ -1,3 +1,8 @@
+2014-01-15  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/59822
+       * g++.dg/torture/pr59822.C: New testcase.
+
 2014-01-15  Kirill Yukhin  <kirill.yukhin@intel.com>
 
        PR target/59808
diff --git a/gcc/testsuite/g++.dg/torture/pr59822.C b/gcc/testsuite/g++.dg/torture/pr59822.C
new file mode 100644 (file)
index 0000000..7357b6d
--- /dev/null
@@ -0,0 +1,14 @@
+// { dg-do compile }
+
+typedef struct rtvec_def *rtvec;
+enum machine_mode { VOIDmode };
+struct rtvec_def { void *elem[1]; };
+extern void *const_tiny_rtx[2];
+void
+ix86_build_const_vector (enum machine_mode mode, bool vect,
+                        void *value, rtvec v, int n_elt)
+{
+  int i;
+  for (i = 1; i < n_elt; ++i)
+    ((v)->elem[i]) = vect ? value : (const_tiny_rtx[(int) (mode)]);
+}
index acdaa2db8afe61c0e10410a9fb2ad4f65911e637..820df7eddba4a068d42ded10a83297637c431608 100644 (file)
@@ -5480,6 +5480,59 @@ permute_vec_elements (tree x, tree y, tree mask_vec, gimple stmt,
   return data_ref;
 }
 
+/* Hoist the definitions of all SSA uses on STMT out of the loop LOOP,
+   inserting them on the loops preheader edge.  Returns true if we
+   were successful in doing so (and thus STMT can be moved then),
+   otherwise returns false.  */
+
+static bool
+hoist_defs_of_uses (gimple stmt, struct loop *loop)
+{
+  ssa_op_iter i;
+  tree op;
+  bool any = false;
+
+  FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
+    {
+      gimple def_stmt = SSA_NAME_DEF_STMT (op);
+      if (!gimple_nop_p (def_stmt)
+         && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
+       {
+         /* Make sure we don't need to recurse.  While we could do
+            so in simple cases when there are more complex use webs
+            we don't have an easy way to preserve stmt order to fulfil
+            dependencies within them.  */
+         tree op2;
+         ssa_op_iter i2;
+         FOR_EACH_SSA_TREE_OPERAND (op2, def_stmt, i2, SSA_OP_USE)
+           {
+             gimple def_stmt2 = SSA_NAME_DEF_STMT (op2);
+             if (!gimple_nop_p (def_stmt2)
+                 && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt2)))
+               return false;
+           }
+         any = true;
+       }
+    }
+
+  if (!any)
+    return true;
+
+  FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
+    {
+      gimple def_stmt = SSA_NAME_DEF_STMT (op);
+      if (!gimple_nop_p (def_stmt)
+         && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
+       {
+         gimple_stmt_iterator gsi = gsi_for_stmt (def_stmt);
+         gsi_remove (&gsi, false);
+         gsi_insert_on_edge_immediate (loop_preheader_edge (loop), def_stmt);
+       }
+    }
+
+  return true;
+}
+
 /* vectorizable_load.
 
    Check if STMT reads a non scalar data-ref (array/pointer/structure) that
@@ -6384,7 +6437,8 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
                  /* If we have versioned for aliasing then we are sure
                     this is a loop invariant load and thus we can insert
                     it on the preheader edge.  */
-                 if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
+                 if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo)
+                     && hoist_defs_of_uses (stmt, loop))
                    {
                      if (dump_enabled_p ())
                        {