[Bug middle-end/64006] __builtin_mul_overflow fails to signal overflow

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Fri Nov 21 10:40:00 GMT 2014


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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2014-11-21
                 CC|                            |jakub at gcc dot gnu.org
   Target Milestone|---                         |5.0
     Ever confirmed|0                           |1

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Reduced testcase:

int v;

long __attribute__ ((noinline))
test (long *x, int y)
{
  int i;
  long s = 1;
  for (i = 0; i < y; i++)
    if (__builtin_mul_overflow (s, x[i], &s))
      v++;
  return s;
}

int
main ()
{
  long d[7] = { 975, 975, 975, 975, 975, 975, 975 };
  long r = test (d, 7);
  if (sizeof (long) * __CHAR_BIT__ == 64 && v != 1)
    __builtin_abort ();
  else if (sizeof (long) * __CHAR_BIT__ == 32 && v != 4)
    __builtin_abort ();
  return 0;
}

The problem is in VRP, the IMAGPART_EXPR of the MUL_OVERFLOW result is
processed with only some edges executable and others not, so the value ranges
of the values are only temporary, not final.  In that case, one of the
arguments of
MUL_OVERFLOW is assumed to be [1, 1] and the other argument is VARYING.
A final [1, 1] * VARYING in the same types is never overflowing though, the
result always fits into the type, so we set [0, 0] as the value range for the
IMAGPART_EXPR.  And for some reason we are not called again when the
MUL_OVERFLOW arguments are VARYING * VARYING.
So, is there some way how to tell VRP to simulate the IMAGPART_EXPR again?  Or
is there a way to see if the value ranges of the *_OVERFLOW arguments are just
temporary simulation or final?  Is the fact that IMAGPART_EXPR range might be
narrower initially and change to larger one later on compatible with VRP at
all?
Though, how is that generally different from say simulating s = s + 4 inside a
loop?  There we initially assume (if s is 1 before the loop) range [5, 5] and
later turn it into a wider range.  Though, for the IMAGPART_EXPR in this case,
the arguments of the MUL_OVERFLOW don't depend on the IMAGPART_EXPR value.



More information about the Gcc-bugs mailing list