https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123384
Bug ID: 123384
Summary: Missing 64-bit to 128-bit widen_mult detection for
pure C implementation
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: middle-end
Assignee: unassigned at gcc dot gnu.org
Reporter: liuhongt at gcc dot gnu.org
Target Milestone: ---
unsigned long long
multiply64to128(unsigned long long lhs, unsigned long long rhs, unsigned long
long *high)
{
/* First calculate all of the cross products. */
unsigned long long lo_lo = (lhs & 0xFFFFFFFF) * (rhs & 0xFFFFFFFF);
unsigned long long hi_lo = (lhs >> 32) * (rhs & 0xFFFFFFFF);
unsigned long long lo_hi = (lhs & 0xFFFFFFFF) * (rhs >> 32);
unsigned long long hi_hi = (lhs >> 32) * (rhs >> 32);
/* Now add the products together. These will never overflow. */
unsigned long long cross = (lo_lo >> 32) + (hi_lo & 0xFFFFFFFF) + lo_hi;
unsigned long long upper = (hi_lo >> 32) + (cross >> 32) + hi_hi;
*high = upper;
return (cross << 32) | (lo_lo & 0xFFFFFFFF);
}
void
ff (unsigned long long a, unsigned long long b, unsigned long long *r)
{
unsigned __int128 result = (unsigned __int128)a * b;
r[0] = result;
r[1] = result >> 64;
}
GCC can handle ff but not for multiply64to128, LLVM can handle both
https://godbolt.org/z/Mc5TGEYMn