aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57343.c22
-rw-r--r--gcc/tree-ssa-loop-niter.c20
4 files changed, 48 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8b7bed8..7d6d31e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2013-05-27 Richard Biener <rguenther@suse.de>
+ PR tree-optimization/57343
+ * tree-ssa-loop-niter.c (number_of_iterations_ne_max): Do not
+ use multiple_of_p if not TYPE_OVERFLOW_UNDEFINED.
+ (number_of_iterations_cond): Do not build the folded tree.
+
+2013-05-27 Richard Biener <rguenther@suse.de>
+
Revert
PR middle-end/57381
* fold-const.c (operand_equal_p): Compare FIELD_DECLs with
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7cf47c4..40c213f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2013-05-27 Richard Biener <rguenther@suse.de>
+ PR tree-optimization/57343
+ * gcc.dg/torture/pr57343.c: New testcase.
+
+2013-05-27 Richard Biener <rguenther@suse.de>
+
PR tree-optimization/57417
* gcc.dg/torture/pr57417.c: New testcase.
diff --git a/gcc/testsuite/gcc.dg/torture/pr57343.c b/gcc/testsuite/gcc.dg/torture/pr57343.c
new file mode 100644
index 0000000..b05bad5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr57343.c
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+
+int c = 0;
+
+int
+main ()
+{
+ int i, f = 1;
+ for (i = 0; i < 5; i++)
+ {
+ --c;
+ unsigned char h = c * 100;
+ if (h == 0)
+ {
+ f = 0;
+ break;
+ }
+ }
+ if (f != 1)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 090e114..f562930 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -552,10 +552,18 @@ number_of_iterations_ne_max (mpz_t bnd, bool no_overflow, tree c, tree s,
{
double_int max;
mpz_t d;
+ tree type = TREE_TYPE (c);
bool bnds_u_valid = ((no_overflow && exit_must_be_taken)
|| mpz_sgn (bnds->below) >= 0);
- if (multiple_of_p (TREE_TYPE (c), c, s))
+ if (integer_onep (s)
+ || (TREE_CODE (c) == INTEGER_CST
+ && TREE_CODE (s) == INTEGER_CST
+ && tree_to_double_int (c).mod (tree_to_double_int (s),
+ TYPE_UNSIGNED (type),
+ EXACT_DIV_EXPR).is_zero ())
+ || (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (c))
+ && multiple_of_p (type, c, s)))
{
/* If C is an exact multiple of S, then its value will be reached before
the induction variable overflows (unless the loop is exited in some
@@ -572,16 +580,15 @@ number_of_iterations_ne_max (mpz_t bnd, bool no_overflow, tree c, tree s,
the whole # of iterations analysis will fail). */
if (!no_overflow)
{
- max = double_int::mask (TYPE_PRECISION (TREE_TYPE (c))
- - tree_low_cst (num_ending_zeros (s), 1));
+ max = double_int::mask (TYPE_PRECISION (type)
+ - tree_low_cst (num_ending_zeros (s), 1));
mpz_set_double_int (bnd, max, true);
return;
}
/* Now we know that the induction variable does not overflow, so the loop
iterates at most (range of type / S) times. */
- mpz_set_double_int (bnd, double_int::mask (TYPE_PRECISION (TREE_TYPE (c))),
- true);
+ mpz_set_double_int (bnd, double_int::mask (TYPE_PRECISION (type)), true);
/* If the induction variable is guaranteed to reach the value of C before
overflow, ... */
@@ -1311,7 +1318,8 @@ number_of_iterations_cond (struct loop *loop,
}
/* If the loop exits immediately, there is nothing to do. */
- if (integer_zerop (fold_build2 (code, boolean_type_node, iv0->base, iv1->base)))
+ tree tem = fold_binary (code, boolean_type_node, iv0->base, iv1->base);
+ if (tem && integer_zerop (tem))
{
niter->niter = build_int_cst (unsigned_type_for (type), 0);
niter->max = double_int_zero;