https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79173
--- Comment #14 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Unfortunately, the clang __builtin_addc* and __builtin_subc* builtins are badly designed. Instead of adding or subtracting a 1-bit carry, where the result is guaranteed to have 1-bit carry as well, they are: unsigned __builtin_addc (unsigned x, unsigned y, unsigned carry_in, unsigned *carry_out) { unsigned r; unsigned c1 = __builtin_add_overflow (x, y, &r); unsigned c2 = __builtin_add_overflow (r, carry_in, &r); *carry_out = c1 + c2; return r; } unsigned __builtin_subc (unsigned x, unsigned y, unsigned carry_in, unsigned *carry_out) { unsigned r; unsigned c1 = __builtin_sub_overflow (x, y, &r); unsigned c2 = __builtin_sub_overflow (r, carry_in, &r); *carry_out = c1 + c2; return r; } So, instead of doing [0, 0xffffffff] + [0, 0xffffffff] + [0, 1] resulting in [0, 0xffffffff] plus [0, 1] carry they actually do [0, 0xffffffff] + [0, 0xffffffff] + [0, 0xffffffff] resulting in [0, 0xffffffff] plus [0, 2] carry. So far for good "design". So, am not really sure if it is worth implementing those builtins, one can use __builtin_add_overflow/__builtin_sub_overflow instead, all we need is pattern detect if they are chained and so start with 0 carry in and then the carry outs are guaranteed to be [0, 1] and further pairs of .ADD_OVERFLOW/.SUB_OVERFLOW again can count on [0, 1] carry in and produce [0, 1] carry out. And pattern detect that into some new IFN which will try to produce efficient code for these.