https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113852
--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> --- Reduced: int main() { unsigned short a1 = (1u << 16) - 1; unsigned short a2 = a1; /* a1 * a2 should be 4294836225 in math terms */ unsigned long long a3 = 4294836225; /* * The result of (a1 * a2) is of type int and the result is negative. * (a1 * a2) ends up as some bogus high number because the common * type here ends up as uint64_t and sign-extension occurs. */ if ((a1 * a2) > a3) { __builtin_abort(); } }