https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108419

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |aldyh at gcc dot gnu.org,
                   |                            |jakub at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Slightly cleaned up testcase:
static int b = 6, c;
long d;
short h, i, j;
signed char k;
void foo (void);
short baz (int, int, int, int, int, int, int);
short qux (unsigned short, int, char, long);

short
bar (short l, short m)
{
  return l + m;
}

static signed char
corge (void)
{
  unsigned n;
  for (n = -10U; n >= 14; n = bar (n, 8))
    {
      i = qux (b, 0, c, b);
      j = baz (i, b, d < j, 5, 7, 9, 5);
      k = 200 + n;
      h = k % 5;
      if (!h)
        foo ();
    }
  return n;
}

int
main ()
{
  b || corge ();
  b = 1;
}

The loop iterates twice, with n -10U and -2U, in third iteration 6U fails the
6U >= 14 condition.
In GCC 12 as well as in r13-439 and r13-440 the loop IV is
  # ivtmp.30_42 = PHI <ivtmp.30_34(8), 190(7)>
and loop condition is
  ivtmp.30_34 = ivtmp.30_42 + 8;
  if (ivtmp.30_34 != 206)
while trunk has 2 IVs:
  # RANGE [irange] unsigned int [38, 32767][4294934528, +INF] NONZERO
0xfffffffe
  # n_32 = PHI <n_30(8), 4294967286(7)>
  # RANGE [irange] unsigned int [1, +INF]
  # ivtmp_2 = PHI <ivtmp_43(8), 2(7)>
and
  # RANGE [irange] unsigned short [30, +INF] NONZERO 0xfffe
  l.0_27 = (unsigned short) n_32;
  # RANGE [irange] unsigned short [0, 7][38, +INF] NONZERO 0xfffe
  _28 = l.0_27 + 8;
  # RANGE [irange] short int [-INF, 7][38, +INF] NONZERO 0xfffe
  _29 = (short int) _28;
  # RANGE [irange] unsigned int [0, 7][38, 32767][4294934528, +INF] NONZERO
0xfffffffe
  n_30 = (unsigned int) _29;
  ivtmp_43 = ivtmp_2 - 1;
  if (ivtmp_43 != 0)

The r13-440 regression is in vrp2, previously we were able to determine that
because ivtmp.30_42 is [190, 190][198, 198]
then (signed char) of that is [-66, -66][-58, -58] and that % 5 is [-3, -3][-1,
-1].
 Folding statement: _24 = (signed char) ivtmp.30_42;
-   Loops range found for ivtmp.30_42: unsigned char [190, 198] and calculated
range :unsigned char [190, 190][198, 205]
-Global Exported: _24 = signed char [-66, -58] ...  irange was : signed char
[-66, -66][-58, -58]
+Global Exported: _24 = signed char [-66, -58]
 Not folded
 Folding statement: k = _24;
 Not folded
 Folding statement: _25 = _24 % 5;
-Global Exported: _25 = signed char [-3, -1] ...  irange was : signed char [-3,
-3][-1, -1]
+Global Exported: _25 = signed char [-4, 0]
is the first difference in the vrp2 dump between r13-439 and r13-440.
The other major change is starting with r13-3486-g4c5b1160776382772 when ivopts
uses the 2 IVs rather than one
and the convoluted increment by 8.  It is actually only a normal increment by 8
if n_32 is in [0, 32759][-32777U, -1U]
but that is actually the case here.

I think the ranger doesn't iterate, right?  So is there any way that it would
figure out the exact range for the IV?

Reply via email to