Jakub Jelinek <ja...@redhat.com> writes: > Hi! > > The following testcase is miscompiled, because wi::mul for (_BitInt(65))-15 > times (_BitInt(65))-15 computes the right value (_BitInt(65))225, but > sets *overflow to wi::OVF_UNKNOWN as that it overflowed when it didn't. > > Even signed operands are unpacked as unsigned but because they are > implicitly sign-extended from the represented value (the operands > obviously have len==1), we get > 0xfffffff1, 0xffffffff, 0x1, 0x0 > in both u and v (0x1 because that is exactly 65 bits). > We then multiply these. Next step is because both the high and > overflow handling expects the high half to start at a limb boundary > the bits of the result starting with bit 65 are shifted up by 63 such > that the bits relevant for high/need_overflow start at the half of the > 4th half wide int limb. > Because both operands are negative that part is then adjusted. > > The reason mul_internal says there is overflow is because of the unspecified > garbage in the most significant bits of the result which the adjusting > doesn't clean up. 65 bit multiplication needs 65 bits of result and 65 bits > of the high part, can't produce more, so the following patch fixes it by > checking for the overflow only in those first 65 bits of the high part, not > anything beyond that. If it was a highpart multiply, we'd have ignored that > as well (canonized).
Nit: canonicalized. to canonize is to become a saint :) thanks, sam