https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110304

--- Comment #1 from cqwrteur <unlvsur at live dot com> ---
Also mine is exactly what GCC would generate exactly the same as clang without
builtin. Clang internally implements this as mine one.

Since on wasm, riscv or loongarch where these architectures do not provide
carry flags. Introducing types like bool that would cause implicit cast would
create performance issues and instructions dependencies. Usually add
instruction can be pipelined very well due to tons of ALU ports are designed
for add.


template<::std::unsigned_integral T>
inline constexpr T add_carry(T a,T b,T carryin,T& carryout) noexcept
{
    [[assume(carryin==0||carryin==1)]];
    a+=b;
    carryout=a<b;
    a+=carryin;
    carryout+=a<carryin;
    return a;
}

Take add_carry as an example. Here you see, all operations are either move,
less than (which is minus technically) or add. The add and move ALU deals with
all the logic of carry here without any logic or bit operation. No branches or
bit operations are involved.

while __builtin_uadd_overflow clearly needs branches to know whether it
overflows.

Reply via email to