Two obvious loop-iv fixes
Jan Hubicka
hubicka@ucw.cz
Sat Oct 13 17:44:00 GMT 2012
Hi,
while proofreading loop-iv for possible cause of the miscompilation that turned
out to be webizer bug I noticed two minor problems.
1) determine_max_iter has path dealing with AND that is bogus, because
constant argument is always canonized to be second. Enabling the path
however somethimes leads to worse results, so I improved it a bit
by combining both estimates.
2) bounds are recorded as signed values intead of unsigned. This means
that values with upper bit set gets promoted to almost infinity for
double int.
Bootstrapped®tested x86_64-linux, comitted as obvious.
Honza
* loop-iv.c (determine_max_iter): Fix handling of AND.
(iv_number_of_iterations): Record upper bounds as unsigned
values.
Index: loop-iv.c
===================================================================
--- loop-iv.c (revision 192409)
+++ loop-iv.c (working copy)
@@ -2224,13 +2224,18 @@ determine_max_iter (struct loop *loop, s
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, s
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 *lo
? 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 *lo
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
More information about the Gcc-patches
mailing list