re PR middle-end/55481 (-O2 generates a wrong-code infinite loop in C++Benchmark...
authorZdenek Dvorak <ook@ucw.cz>
Wed, 12 Dec 2012 13:07:19 +0000 (14:07 +0100)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 12 Dec 2012 13:07:19 +0000 (13:07 +0000)
2012-12-12  Zdenek Dvorak  <ook@ucw.cz>

PR tree-optimization/55481
* tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Fall
back to general rewriting if we cannot leave an original biv
definition alone.

* gcc.dg/torture/pr55481.c: New testcase.

From-SVN: r194444

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr55481.c [new file with mode: 0644]
gcc/tree-ssa-loop-ivopts.c

index 334a3ca384b1ed8acda3f2983241a2b423e5c3ee..d9630ed74146fe04dde65eb6542fb764eeabfd63 100644 (file)
@@ -1,3 +1,10 @@
+2012-12-12  Zdenek Dvorak  <ook@ucw.cz>
+
+       PR tree-optimization/55481
+       * tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Fall
+       back to general rewriting if we cannot leave an original biv
+       definition alone.
+
 2012-12-12  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/55659
index f9a68a5be6bc8341684f7d464c0bad420a71a461..35e21d682d65905a13f01e34050305986174f4a8 100644 (file)
@@ -1,3 +1,8 @@
+2012-12-12  Zdenek Dvorak  <ook@ucw.cz>
+
+       PR tree-optimization/55481
+       * gcc.dg/torture/pr55481.c: New testcase.
+
 2012-12-12  Steven Bosscher  <steven@gcc.gnu.org>
            Jakub Jelinek  <jakub@redhat.com>
 
diff --git a/gcc/testsuite/gcc.dg/torture/pr55481.c b/gcc/testsuite/gcc.dg/torture/pr55481.c
new file mode 100644 (file)
index 0000000..26ba9ff
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+
+int main()
+{
+  signed char result = 0;
+  int n;
+  for (n = 0; n < 13; ++n)
+    {
+      int tem = result;
+      tem = tem + 31;
+      result = tem;
+    }
+  if (result != -109)
+    __builtin_abort ();
+  return 0;
+}
index 1e41fa94a731148342a7eb746d7615182137d260..c33fc7c6b8f6b8e5415381dc4a675dda58fdb936 100644 (file)
@@ -6088,35 +6088,24 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
   if (cand->pos == IP_ORIGINAL
       && cand->incremented_at == use->stmt)
     {
-      tree step, ctype, utype;
-      enum tree_code incr_code = PLUS_EXPR, old_code;
+      enum tree_code stmt_code;
 
       gcc_assert (is_gimple_assign (use->stmt));
       gcc_assert (gimple_assign_lhs (use->stmt) == cand->var_after);
 
-      step = cand->iv->step;
-      ctype = TREE_TYPE (step);
-      utype = TREE_TYPE (cand->var_after);
-      if (TREE_CODE (step) == NEGATE_EXPR)
-       {
-         incr_code = MINUS_EXPR;
-         step = TREE_OPERAND (step, 0);
-       }
-
       /* Check whether we may leave the computation unchanged.
         This is the case only if it does not rely on other
         computations in the loop -- otherwise, the computation
         we rely upon may be removed in remove_unused_ivs,
         thus leading to ICE.  */
-      old_code = gimple_assign_rhs_code (use->stmt);
-      if (old_code == PLUS_EXPR
-         || old_code == MINUS_EXPR
-         || old_code == POINTER_PLUS_EXPR)
+      stmt_code = gimple_assign_rhs_code (use->stmt);
+      if (stmt_code == PLUS_EXPR
+         || stmt_code == MINUS_EXPR
+         || stmt_code == POINTER_PLUS_EXPR)
        {
          if (gimple_assign_rhs1 (use->stmt) == cand->var_before)
            op = gimple_assign_rhs2 (use->stmt);
-         else if (old_code != MINUS_EXPR
-                  && gimple_assign_rhs2 (use->stmt) == cand->var_before)
+         else if (gimple_assign_rhs2 (use->stmt) == cand->var_before)
            op = gimple_assign_rhs1 (use->stmt);
          else
            op = NULL_TREE;
@@ -6124,24 +6113,13 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
       else
        op = NULL_TREE;
 
-      if (op
-         && (TREE_CODE (op) == INTEGER_CST
-             || operand_equal_p (op, step, 0)))
+      if (op && expr_invariant_in_loop_p (data->current_loop, op))
        return;
-
-      /* Otherwise, add the necessary computations to express
-        the iv.  */
-      op = fold_convert (ctype, cand->var_before);
-      comp = fold_convert (utype,
-                          build2 (incr_code, ctype, op,
-                                  unshare_expr (step)));
-    }
-  else
-    {
-      comp = get_computation (data->current_loop, use, cand);
-      gcc_assert (comp != NULL_TREE);
     }
 
+  comp = get_computation (data->current_loop, use, cand);
+  gcc_assert (comp != NULL_TREE);
+
   switch (gimple_code (use->stmt))
     {
     case GIMPLE_PHI: