Skip to content

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

@Explorer09

Description

@Explorer09

https://godbolt.org/z/oW3nq5aKM

#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 clang 21.1.0 with -Os option:

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 need to be an atomic calculation, so I think the optimization from func1_a to func1_b is allowed.

(Bug report in GCC)

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions