https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96289
Bug ID: 96289 Summary: Unnecessary saving and re-testing of the carry flag with __builtin_usub_overflow Product: gcc Version: 10.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: josephcsible at gmail dot com Target Milestone: --- Target: x86_64-linux-gnu Consider this C code: unsigned f(unsigned x, unsigned y) { if (__builtin_usub_overflow(x, y, &x)) { x += 100; } return x; } When compiled with -O3, it produces the following assembly: f: xorl %edx, %edx subl %esi, %edi setb %dl leal 100(%rdi), %eax testl %edx, %edx cmove %edi, %eax ret https://godbolt.org/z/WMo377 But "lea" doesn't affect the carry flag (or any flags for that matter), so there's no need to save it to a register and then re-test it. It should have produced this assembly instead: f: subl %esi, %edi leal 100(%rdi), %eax cmovae %edi, %eax ret