On 11/02/2013 07:06 AM, Richard Sandiford wrote:
The first part of this is a simple type mismatch -- get_max_loop_iterations
returns a widest_int aka max_wide_int -- and I'd have installed it as
obvious. The second part isn't as obvious though. The old code stored
the maximum iterations as:
if (!get_max_loop_iterations (loop, &iter)
|| !iter.fits_shwi ())
iterations_max = const0_rtx;
else
iterations_max = GEN_INT (iter.to_shwi ());
and the new code uses:
if (!get_max_loop_iterations (loop, &iter)
|| !wi::fits_shwi_p (iter))
iterations_max = const0_rtx;
else
iterations_max = immed_wide_int_const (iter, mode);
which includes an extra canonicalisation. I agree it would be good to do
that in principle, but I'm not sure it copes correctly with the case where
the loop iterates 1 << GET_MODE_PRECISION (mode) times. Plus I think the
real fix would be to avoid the host dependence altogether, i.e. get rid
of the fits_shwi_p too.
As it stands, this breaks bfin-elf's pattern, which has:
/* Due to limitations in the hardware (an initial loop count of 0
does not loop 2^32 times) we must avoid to generate a hardware
loops when we cannot rule out this case. */
if (!flag_unsafe_loop_optimizations
&& (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 0xFFFFFFFF)
FAIL;
With the sign-extending conversion, this now triggers more often than
it was supposed to.
Since the old "GEN_INT (iter.to_shwi ());" works verbatim in wide-int too,
and since we still use that form in the doloop_begin code, I think we should
just back the immed_wide_int_const out.
Tested on powerpc64-linux-gnu and x86_64-linux-gnu. It fixes some
unwanted testsuite changes in bfin-elf. OK to install?
I dislike this a lot. I think that this is a badly written pattern
in the bfin port if it depends on the host size. As machines get
bigger, (they may not be getting faster but they are still getting
bigger) having traps like this at the portable level will bite us.
in truth this code should really be iterations_max =
immed_wide_int_const (iter, mode) with no tests at all.
Thanks,
Richard
Index: gcc/loop-doloop.c
===================================================================
--- gcc/loop-doloop.c 2013-11-02 10:49:37.463178153 +0000
+++ gcc/loop-doloop.c 2013-11-02 10:49:55.927314661 +0000
@@ -549,7 +549,7 @@ doloop_modify (struct loop *loop, struct
{
rtx init;
unsigned level = get_loop_level (loop) + 1;
- wide_int iter;
+ widest_int iter;
rtx iter_rtx;
if (!get_max_loop_iterations (loop, &iter)
@@ -673,7 +673,7 @@ doloop_optimize (struct loop *loop)
|| !wi::fits_shwi_p (iter))
iterations_max = const0_rtx;
else
- iterations_max = immed_wide_int_const (iter, mode);
+ iterations_max = GEN_INT (iter.to_shwi ());
level = get_loop_level (loop) + 1;
/* Generate looping insn. If the pattern FAILs then give up trying