aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2012-06-27 11:32:30 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2012-06-27 11:32:30 +0000
commit195b4c507f3c0552ac78530513e4da5d227215c6 (patch)
treed0a3413286a82915919c9aaf8c25c24327aaa711
parentbe7493cabbc288d598ac3ede0fc8395e780d1cfa (diff)
downloadgcc-195b4c507f3c0552ac78530513e4da5d227215c6.zip
gcc-195b4c507f3c0552ac78530513e4da5d227215c6.tar.gz
gcc-195b4c507f3c0552ac78530513e4da5d227215c6.tar.bz2
re PR middle-end/53676 (empty loop is not always removed now)
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
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/scev-6.c23
-rw-r--r--gcc/tree-chrec.c17
-rw-r--r--gcc/tree-scalar-evolution.c25
5 files changed, 80 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 441f647..82309f8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,16 @@
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
* tree-ssa-reassoc.c (get_rank): All default defs have
precomputed rank.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 87c5d49..2b4c5c8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..3b02374
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-6.c
@@ -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" } } */
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c
index 38dca4a..82c3771 100644
--- a/gcc/tree-chrec.c
+++ b/gcc/tree-chrec.c
@@ -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);
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 21d1fd0..486197e 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -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;