------- Comment #1 from scovich at gmail dot com 2007-06-06 03:39 ------- Happens on x86_64-unknown-linux-gnu as well, for both 4.2.0 and 4.3 (20070605)
The problem is even worse for 128-bit arithmetic because it has to check two registers (with associated branches) before making a decision. This in spite of the fact that sbb sets the flags properly AFAIK: bool sub128(__uint128_t &dest, __uint128_t a, __uint128_t b) { dest = a - b; if(dest > a) abort(); } _Z6sub128Rooo: .LFB557: movq %rsi, %rax movq %rdx, %r10 pushq %rbx .LCFI0: subq %rcx, %rax sbbq %r8, %rdx movq %rax, (%rdi) cmpq %rdx, %r10 movq %rdx, 8(%rdi) ja .L23 jae .L24 .L21: call abort .p2align 4,,7 .L24: cmpq %rax, %rsi .p2align 4,,6 jb .L21 .p2align 4,,7 .L23: popq %rbx .p2align 4,,5 ret There's not really a way to work around it with inline asm, either, because of the branch on overflow that will most likely come right afterward... -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30315