https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91373
Andrew Pinski <pinskia at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> --- U16_0 * U16_1 Is really: ((int)(U16_0)) * ((int)(U16_1)) Due to C/C++ promption rules. Which means in this case, it overflows and since both were positive (due to u16 promoting to int) to begin with, shifting to get to the sign bit will always be 0. If you want to unsigned 32 as the type, then you need to explictly cast it.