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.

Reply via email to