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?

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

Reply via email to