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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |wrong-code
             Status|REOPENED                    |NEW
          Component|c                           |tree-optimization

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
It's still true that L*k is still an int multiplication and if that overflows
the behavior is undefined.

In .original you can see

  if (k >= 0 && k < n)
    {
      *(a + (sizetype) ((long unsigned int) (L * k) * 8)) = 0.0;
    }

which means the FE only makes sure to carry out the multiplication by the
element size in sizetype, the index multiplication is done as written.

-fno-strict-overflow or -fwrapv fix the bug.

ubsan instruments like

  if (_12 != 0)
    goto <bb 4>;
  else
    goto <bb 5>;

  <bb 4>:
  _14 = UBSAN_CHECK_MUL (L_13(D), k_8);
  _15 = (long unsigned int) _14;
  _16 = _15 * 8;
  _18 = a_17(D) + _16;

so it seems it should catch overflow there (and it doesn't overflow here).

IVOPTs OTOH rewrites the IV to sth with initial value computed as

 a + ((sizetype)(L * -m) * 8)

We increment that IV by (sizetype)L * 8.

That's bogus as L * -m might overflow in int.

Now the question is how it arrives at this initial value.

Reply via email to