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

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, e.g. looking at the first one, the code seems to be fine before
bitintlower1:
  _BitInt(257) _1;
  unsigned _BitInt(400) _2;

  <bb 2> [local count: 1073741824]:
  _1 = -a_3(D);
  _2 = (unsigned _BitInt(400)) _1;
  <retval> = _2;
But what bitintlower1 does seems to be wrong.  There is a loop doing the
negation for the low 256 bits, that is all correct.  _10 from that loop is the
borrow, 1 in this testcase.  What it does after that looks wrong:
  <bb 4> [local count: 1073741824]:
  _26 = MEM <unsigned long> [(_BitInt(257) *)&a + 32B];
  _27 = (<unnamed-signed:1>) _26;
  _28 = (<unnamed-signed:1>) _10;
  _29 = 0 - _27;
  _30 = _29 - _28;
  _31 = (unsigned long) _30;
  MEM <unsigned long> [(unsigned _BitInt(400) *)&<retval> + 32B] = _31;
Now, _26 is also 1 (or garbage in upper bits and 1 in the least significant
one.
So, _27 and _28 are both -1.
So, we do _29 = 0 - -1; which is not representable in <unnamed-signed:1>, and
then subtract another -1 from it.
I'd say we should be performing those in <unnamed-unsigned:1> type instead and
only cast to <unnamed-signed:1> after all the +/- operations, in order not to
invoke UB in the IL.

Reply via email to