------- Comment #5 from jakub at gcc dot gnu dot org 2010-01-13 15:05 -------
The bug is in add_double_with_sign it seems.
319int
320add_double_with_sign (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
321 unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
322 unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
323 bool unsigned_p)
324{
325 unsigned HOST_WIDE_INT l;
326 HOST_WIDE_INT h;
327
328 l = l1 + l2;
329 h = h1 + h2 + (l < l1);
330
331 *lv = l;
332 *hv = h;
333
334 if (unsigned_p)
335 return (unsigned HOST_WIDE_INT) h < (unsigned HOST_WIDE_INT) h1;
336 else
337 return OVERFLOW_SUM_SIGN (h1, h2, h);
338}
When called with say -1U, -1, -2U, -1, &x, &y, true it pretends no overflow
happened. That is because we don't add just 2 numbers together, but 3 (also (l
< l1)), and so -1U + -1U + 1 gives -1U, so h == h1. I believe it is wrong not
just for unsigned_p, but also for !unsigned_p. The question is how to fix this
as efficiently as possible.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42721