llvm / llvm/llvm-project

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

Open
#161,036 14 comments 0 reactions 1 assignee Claimed by @ckoparkar View on GitHub
good first issue llvm:SelectionDAG missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

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

```C
#include

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
```asm
subIfNoUnderflow_clang:
mov rax, rdi
sub rax, rsi
cmp rax, rdi
cmovae rax, rdi
ret
```

Ideally it should produce:
```asm
subIfNoUnderflow_ideal:
mov rax, rdi
sub rax, rsi
cmovb rax, rdi
ret
```

# Related issues
#53432
#62696
#73847

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.