This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug other/82547] wide_int is not setting overflow properly for large unsigned add/subtract calculations.


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

--- Comment #1 from Andrew Macleod <amacleod at redhat dot com> ---
On a further note, this appears to be because wide_int tries not to use all the
words is it can sign extend?

the sequence with the issue is:
 Mn = wi::min_value (128, UNSIGNED);
 Mx = wi::max_value (128, UNSIGNED);
 Mxminus2  = wi::sub (Mx, 2, UNSIGNED, &ov);
 x = wi::sub (Mn, Mxminus2 , UNSIGNED, &ov2);
 fprintf (stderr, "ov %d  ov2 %d\n", ov, ov2);

if I look at Mn, I see:

(gdb) p Mn.dump()
[...,0], precision = 128

(gdb) p Mn
$14 = {<wide_int_storage> = {val = {0, 140737488344128, 34794152}, len = 1,
precision = 128}, static is_sign_extended = <optimized out>}

So the precision is 128, but len is set to 1 on a 64 bit host.
Same thing happens for Mx.

Then when wi::sub_large is called, it does the calculation and checks:
 if (len * HOST_BITS_PER_WIDE_INT < prec)
    {
      val[len] = mask0 - mask1 - borrow;
      len++;
      if (overflow)
        *overflow = false;
    }

Since both values have a len of 1, and precision is 128, it decides there
cannot be an overflow.  It seems to be ignoring that fgact that sign-extension
may exist.


Interestingly, if I remove that entire hunk of code, and and let it do the
general check for overflow which follows, It works as I would expect.

Of course, I have no idea what the side effects of that are... 
I leave it in the hands of a wide_int expert.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]