On Tue, Mar 05, 2013 at 10:07:50AM +0100, Marek Polacek wrote:
> + if (compare_count.scmp (double_int_zero) == -1)
> + compare_count = double_int_zero;
> + if (loop_count.scmp (double_int_zero) == -1)
> + loop_count = double_int_zero;
Use if (compare_count.is_negative ()) etc. instead?
> - probability = (double) REG_BR_PROB_BASE * compare_count / loop_count;
> - predict_edge (then_edge, PRED_LOOP_IV_COMPARE, probability);
> + {
> + tem = compare_count.divmod_with_overflow (loop_count,
> + 0, TRUNC_DIV_EXPR,
> + &mod, &of);
This is wrong. As compare_count is < loop_count, this will always yield
zero.
I guess you want something like:
/* If loop_count is too big, such that REG_BR_PROB_BASE * loop_count
could overflow, shift both loop_count and compare_count right a bit
so that it doesn't overflow. Note both counts are known not to be
negative at this point. */
int clz_bits = clz_hwi (loop_count.high);
gcc_assert (REG_BR_PROB_BASE < 32768);
if (clz_bits < 16)
{
loop_count.arshift (16 - clz_bits, HOST_BITS_PER_DOUBLE_INT);
compare_count.arshift (16 - clz_bits, HOST_BITS_PER_DOUBLE_INT);
}
tem = loop_count.mul_with_sign (double_int::from_shwi (REG_BR_PROB_BASE),
true, &of);
gcc_assert (!of);
tem = tem.divmod (loop_count, true, TRUNC_DIV_EXPR, &mod);
probability = tem.to_uhwi ();
predict_edge (then_edge, PRED_LOOP_IV_COMPARE, probability);
Jakub