llvm/llvm-project

[x86][armv8] Failure to use flag in unsigned underflow compare idiom

Open

#161,036 建立於 2025年9月28日

在 GitHub 查看
 (14 留言) (0 反應) (1 負責人)C++ (10,782 fork)batch import
good first issuellvm:SelectionDAGmissed-optimization

倉庫指標

Star
 (26,378 star)
PR 合併指標
 (平均合併 1天 2小時) (30 天內合併 1,000 個 PR)

描述

It is a common idiom to check for unsigned underflow by doing a greater than compare between the difference and minuend:

#include <stdint.h>

uint64_t subIfNoUnderflow_clang(uint64_t a, uint64_t b) {
    uint64_t diff = a - b;
    return (diff > a)? a : diff;
}

Instead of using the carry flag, which is set by the subtraction, clang emits a compare instruction:

https://godbolt.org/z/ex5554M6P

subIfNoUnderflow_clang:
        mov     rax, rdi
        sub     rax, rsi
        cmp     rax, rdi
        cmovae  rax, rdi
        ret

Ideally it should produce:

subIfNoUnderflow_ideal:
        mov     rax, rdi
        sub     rax, rsi
        cmovb   rax, rdi
        ret

Related issues

#53432 #62696 #73847

貢獻者指南