(x86 & ARM) Missed subtract overflow pattern on an unsigned loop counter
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
https://godbolt.org/z/EzjEoehfM
```c
void func1_a(unsigned long x, unsigned long y) {
while (1) {
__asm__ ("" ::: "memory");
if (x < y)
break;
x -= y;
}
}
void func1_b(unsigned long x, unsigned long y) {
while (1) {
__asm__ ("" ::: "memory");
if (x - y > x)
break;
x -= y;
}
}
void func1_c(unsigned long x, unsigned long y) {
while (1) {
__asm__ ("" ::: "memory");
if (__builtin_usubl_overflow(x, y, &x))
break;
}
}
```
x86-64 clang 21.1.0 with `-Os` option produces:
```assembly
func1_a:
addq %rsi, %rdi
.LBB0_1:
subq %rsi, %rdi
cmpq %rsi, %rdi
jae .LBB0_1
retq
func1_b:
addq %rsi, %rdi
.LBB1_1:
subq %rsi, %rdi
cmpq %rdi, %rsi
jbe .LBB1_1
retq
func1_c:
.LBB2_1:
subq %rsi, %rdi
jae .LBB2_1
retq
```
Clang doesn't recognize `func1_a` and `func1_b` can both optimize to `func1_c`.
(Similar issue can also happen with ARM and AArch64 targets.)
This issue might be related to #161036, but I can't tell whether my report is a duplicate, since my test code uses a loop.
Contributor guide
Assessment
This issue has not been assessed yet.