llvm / llvm/llvm-project

RISC-V optimization: builtin_sub_overflow(unsigned) can make sub-optimal code

Open
#170,634 1 comment 0 reactions 1 assignee Claimed by @aabhinavg1 View on GitHub
backend:RISC-V llvm:instcombine missed-optimization
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

https://godbolt.org/z/oW3nq5aKM

```c
#include
unsigned long func1_a(unsigned long x, unsigned long y) {
if (__builtin_usubl_overflow(x, y, &x))
return 0x123;
return x;
}
unsigned long func1_b(unsigned long x, unsigned long y) {
if (x < y)
return 0x123;
return x - y;
}
unsigned long func1_c(unsigned long x, unsigned long y) {
if (x - y > x)
return 0x123;
return x - y;
}
```

rv64 clang 21.1.0 with `-Os` option:

```assembly
func1_a:
mv a2, a0
sub a0, a0, a1
bgeu a2, a0, .LBB0_2
li a0, 291
.LBB0_2:
ret

func1_b:
bgeu a0, a1, .LBB1_2
li a0, 291
ret
.LBB1_2:
sub a0, a0, a1
ret
```

A `__builtin_sub_overflow(x, y, ...)` with unsigned integers makes a slightly worse code than a simple `(x < y)` conditional. GCC documentation doesn't say that `__builtin_sub_overflow` needs to be an atomic calculation, so I think the optimization from `func1_a` to `func1_b` is allowed.

([Bug report in GCC](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122998))

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.