https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108292
--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The assembly difference is - movl $1, x+20(%rip) + movl $-6, x+20(%rip) Now, that is the correct value to be stored into x[5] by the __builtin_sub_overflow (0, 6, &x[5]); statement, but each element is then shifted right by (element != 0) ? 31 : 0, so in this case -6U >> 31 aka 1.