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

            Bug ID: 110304
           Summary: __builtin_adcs missing and you miss the point of
                    builtin_adcb
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: unlvsur at live dot com
  Target Milestone: ---

https://github.com/gcc-mirror/gcc/commit/2b4e0415ad664cdb3ce87d1f7eee5ca26911a05b#

This does not include __builtin_adcb, __builtin_adcs and __builtin_subcb,
__builtin_subcs

"
While the design of these builtins in clang is questionable,
rather than being say
unsigned __builtin_addc (unsigned, unsigned, bool, bool *)
"

You miss the point of the point when it falls back to architectures like mips,
wasm, riscv or loongarch where they do not provide flags at all:

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;
}


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

Mine is much faster than your __builtin_uadd_overflow on these architectures.

 #define __builtin_addc(a,b,carry_in,carry_out) \
  ({ unsigned _s; \
     unsigned _c1 = __builtin_uadd_overflow (a, b, &_s); \
     unsigned _c2 = __builtin_uadd_overflow (_s, carry_in, &_s); \
     *(carry_out) = (_c1 | _c2); \
     _s; })

Reply via email to