summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/loop-iv.c27
2 files changed, 25 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 804d74053d6..000b0d2cfea 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2012-10-13 Jan Hubicka <jh@suse.cz>
+
+ * loop-iv.c (determine_max_iter): Fix handling of AND.
+ (iv_number_of_iterations): Record upper bounds as unsigned
+ values.
+
2012-10-13 Steven Bosscher <steven@gcc.gnu.org>
* ira.c (ira): Set current_loops to &ira_loops before recording
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index 658f20360f7..f1e19d82072 100644
--- a/gcc/loop-iv.c
+++ b/gcc/loop-iv.c
@@ -2224,13 +2224,18 @@ determine_max_iter (struct loop *loop, struct niter_desc *desc, rtx old_niter)
rtx niter = desc->niter_expr;
rtx mmin, mmax, cmp;
unsigned HOST_WIDEST_INT nmax, inc;
+ unsigned HOST_WIDEST_INT andmax = 0;
+
+ /* We used to look for constant operand 0 of AND,
+ but canonicalization should always make this impossible. */
+ gcc_checking_assert (GET_CODE (niter) != AND
+ || !CONST_INT_P (XEXP (niter, 0)));
if (GET_CODE (niter) == AND
- && CONST_INT_P (XEXP (niter, 0)))
+ && CONST_INT_P (XEXP (niter, 1)))
{
- nmax = INTVAL (XEXP (niter, 0));
- if (!(nmax & (nmax + 1)))
- return nmax;
+ andmax = UINTVAL (XEXP (niter, 1));
+ niter = XEXP (niter, 0);
}
get_mode_bounds (desc->mode, desc->signed_p, desc->mode, &mmin, &mmax);
@@ -2258,7 +2263,13 @@ determine_max_iter (struct loop *loop, struct niter_desc *desc, rtx old_niter)
if (dump_file)
fprintf (dump_file, ";; improved upper bound by one.\n");
}
- return nmax / inc;
+ nmax /= inc;
+ if (andmax)
+ nmax = MIN (nmax, andmax);
+ if (dump_file)
+ fprintf (dump_file, ";; Determined upper bound "HOST_WIDEST_INT_PRINT_DEC".\n",
+ nmax);
+ return nmax;
}
/* Computes number of iterations of the CONDITION in INSN in LOOP and stores
@@ -2563,7 +2574,7 @@ iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition,
? iv0.base
: mode_mmin);
max = (up - down) / inc + 1;
- record_niter_bound (loop, double_int::from_shwi (max),
+ record_niter_bound (loop, double_int::from_uhwi (max),
false, true);
if (iv0.step == const0_rtx)
@@ -2776,14 +2787,14 @@ iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition,
desc->const_iter = true;
desc->niter = val & GET_MODE_MASK (desc->mode);
- record_niter_bound (loop, double_int::from_shwi (desc->niter),
+ record_niter_bound (loop, double_int::from_uhwi (desc->niter),
false, true);
}
else
{
max = determine_max_iter (loop, desc, old_niter);
gcc_assert (max);
- record_niter_bound (loop, double_int::from_shwi (max),
+ record_niter_bound (loop, double_int::from_uhwi (max),
false, true);
/* simplify_using_initial_values does a copy propagation on the registers