re PR middle-end/53676 (empty loop is not always removed now)
authorRichard Guenther <rguenther@suse.de>
Wed, 27 Jun 2012 11:32:30 +0000 (11:32 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 27 Jun 2012 11:32:30 +0000 (11:32 +0000)
2012-06-27  Richard Guenther  <rguenther@suse.de>

PR middle-end/53676
* tree-chrec.c (chrec_convert_1): Represent truncation to
a type with undefined overflow as truncation to an unsigned
type converted to the type with undefined overflow.
* tree-scalar-evolution.c (interpret_rhs_expr): For computing
the scalar evolution of a truncated widened operation avoid
looking at the non-existing evolution of the widened operation
result.

* gcc.dg/tree-ssa/scev-6.c: New testcase.

From-SVN: r189013

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/scev-6.c [new file with mode: 0644]
gcc/tree-chrec.c
gcc/tree-scalar-evolution.c

index 441f647585bcd968f2936bb04b235c45bea093bc..82309f8d4eab979f336b9b1173ce31cdfea6008f 100644 (file)
@@ -1,3 +1,14 @@
+2012-06-27  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/53676
+       * tree-chrec.c (chrec_convert_1): Represent truncation to
+       a type with undefined overflow as truncation to an unsigned
+       type converted to the type with undefined overflow.
+       * tree-scalar-evolution.c (interpret_rhs_expr): For computing
+       the scalar evolution of a truncated widened operation avoid
+       looking at the non-existing evolution of the widened operation
+       result.
+
 2012-06-27  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/53774
index 87c5d496216d31f43c35dae4204faf2894c2670b..2b4c5c83a499f6e95294293d8508efb8bd0db551 100644 (file)
@@ -1,3 +1,8 @@
+2012-06-27  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/53676
+       * gcc.dg/tree-ssa/scev-6.c: New testcase.
+
 2012-06-26  Janis Johnson  <janisjo@codesourcery.com>
 
        * lib/scandump.exp (scan-dump, scan-dump-not, scan-dump-dem,
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-6.c b/gcc/testsuite/gcc.dg/tree-ssa/scev-6.c
new file mode 100644 (file)
index 0000000..3b02374
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int main()
+{
+  int i;
+  signed char result = 0;
+  for (i = 0; i != 8000; ++i)
+    {
+      int tem = result;
+      tem = tem + 2;
+      result = tem;
+    }
+  if (__builtin_abs ((int)(signed char)((unsigned char ) result + 128)) != 0)
+    __builtin_abort ();
+  return 0;
+}
+
+/* SCEV constant propagation should be able to compute the overall effect
+   of the loop.  */
+
+/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
index 38dca4ab1dd4924b5c50537fc525abe9f4363b42..82c3771b8a598356ea962c1949ae5c00c69187f8 100644 (file)
@@ -1365,6 +1365,23 @@ keep_cast:
     res = fold_build2 (TREE_CODE (chrec), type,
                       fold_convert (type, TREE_OPERAND (chrec, 0)),
                       fold_convert (type, TREE_OPERAND (chrec, 1)));
+  /* Similar perform the trick that (signed char)((int)x + 2) can be
+     narrowed to (signed char)((unsigned char)x + 2).  */
+  else if (use_overflow_semantics
+          && TREE_CODE (chrec) == POLYNOMIAL_CHREC
+          && TREE_CODE (ct) == INTEGER_TYPE
+          && TREE_CODE (type) == INTEGER_TYPE
+          && TYPE_OVERFLOW_UNDEFINED (type)
+          && TYPE_PRECISION (type) < TYPE_PRECISION (ct))
+    {
+      tree utype = unsigned_type_for (type);
+      res = build_polynomial_chrec (CHREC_VARIABLE (chrec),
+                                   fold_convert (utype,
+                                                 CHREC_LEFT (chrec)),
+                                   fold_convert (utype,
+                                                 CHREC_RIGHT (chrec)));
+      res = chrec_convert_1 (type, res, at_stmt, use_overflow_semantics);
+    }
   else
     res = fold_convert (type, chrec);
 
index 21d1fd0a4a153908eb1941cd2cfc8cad526d289f..486197e88a760384468e26484a9d9b4c274ef329 100644 (file)
@@ -1634,6 +1634,7 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt,
                    tree type, tree rhs1, enum tree_code code, tree rhs2)
 {
   tree res, chrec1, chrec2;
+  gimple def;
 
   if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
     {
@@ -1759,7 +1760,29 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt,
       break;
 
     CASE_CONVERT:
-      chrec1 = analyze_scalar_evolution (loop, rhs1);
+      /* In case we have a truncation of a widened operation that in
+         the truncated type has undefined overflow behavior analyze
+        the operation done in an unsigned type of the same precision
+        as the final truncation.  We cannot derive a scalar evolution
+        for the widened operation but for the truncated result.  */
+      if (TREE_CODE (type) == INTEGER_TYPE
+         && TREE_CODE (TREE_TYPE (rhs1)) == INTEGER_TYPE
+         && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (rhs1))
+         && TYPE_OVERFLOW_UNDEFINED (type)
+         && TREE_CODE (rhs1) == SSA_NAME
+         && (def = SSA_NAME_DEF_STMT (rhs1))
+         && is_gimple_assign (def)
+         && TREE_CODE_CLASS (gimple_assign_rhs_code (def)) == tcc_binary
+         && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
+       {
+         tree utype = unsigned_type_for (type);
+         chrec1 = interpret_rhs_expr (loop, at_stmt, utype,
+                                      gimple_assign_rhs1 (def),
+                                      gimple_assign_rhs_code (def),
+                                      gimple_assign_rhs2 (def));
+       }
+      else
+       chrec1 = analyze_scalar_evolution (loop, rhs1);
       res = chrec_convert (type, chrec1, at_stmt);
       break;