https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107564
Bug ID: 107564 Summary: Fail to recognize overflow check for addition of __uint128_t operands Product: gcc Version: 12.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: cassio.neri at gmail dot com Target Milestone: --- Consider: char f128(__uint128_t m, __uint128_t n) { #if !defined(USE_BUILTIN_ADD_OVERFLOW) m += n; return m < n; #else __uint128_t r; return __builtin_add_overflow(m, n, &r); #endif } When USE_BUILTIN_ADD_OVERFLOW is undefined, GCC fails to recognise this is an overflow check and with -O3 generates this: mov r8, rdi mov rax, rsi mov rdi, rax mov rsi, r8 mov rax, rdx mov rdx, rcx add rsi, rax adc rdi, rcx cmp rsi, rax mov rcx, rdi sbb rcx, rdx setc al ret When USE_BUILTIN_ADD_OVERFLOW is defined, it generates better code but still suboptimal: mov r8, rdi mov rax, rsi mov rsi, r8 mov rdi, rax add rsi, rdx adc rdi, rcx setc al ret For other unsigned integer types GCC generates the same optimal code for both methods. For instance for uint64_t: add rdi, rsi setc al ret https://godbolt.org/z/bj4M5no4j