https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99620
Bug ID: 99620 Summary: Subtract with borrow (SBB) missed optimization Product: gcc Version: 10.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: chfast at gmail dot com Target Milestone: --- Hi. For the 128-bit precision subtraction: SUB + SBB the optimization depends on the how the carry bit condition is specified in the code. In the first case below everything works nicely, but in the second we have unnecessary CMP in the final code. I believe the second carry bit condition is simpler (does not require unsigned integer wrapping behavior) and does not have dependency on the first subtraction. using u64 = unsigned long; struct u128 { u64 l; u64 h; }; auto sub_good(u128 a, u128 b) { auto l = a.l - b.l; auto k = l > a.l; auto h = a.h - b.h - k; return u128{l, h}; } auto sub_bad(u128 a, u128 b) { auto l = a.l - b.l; auto k = a.l < b.l; auto h = a.h - b.h - k; return u128{l, h}; } sub_good(u128, u128): mov rax, rdi sub rax, rdx sbb rsi, rcx mov rdx, rsi ret sub_bad(u128, u128): cmp rdi, rdx mov rax, rdi sbb rsi, rcx sub rax, rdx mov rdx, rsi ret If you think this is easy to fix, I would like to give it a try if I could get some pointers where to start.