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

Reply via email to