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

Reply via email to