https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122998
Bug ID: 122998
Summary: RISC-V optimization: builtin_sub_overflow(unsigned)
can make sub-optimal code
Product: gcc
Version: 15.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: Explorer09 at gmail dot com
Target Milestone: ---
https://godbolt.org/z/b9GP33rTE
```c
#include <stdbool.h>
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 gcc 15.2 with `-Os` optimization:
```assembly
func1_a:
sub a1,a0,a1
bltu a0,a1,.L5
mv a0,a1
ret
.L5:
li a0,291
ret
func1_b:
bltu a0,a1,.L8
sub a0,a0,a1
ret
.L8:
li a0,291
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` need to be an atomic calculation, so I think the
optimization from `func1_a` to `func1_b` is allowed.