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

--- Comment #29 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Vincent Lefèvre from comment #28)
> (In reply to Jakub Jelinek from comment #27)
> > Given that the builtins exist for 10 years already, I think changing it for
> > them is too late, though they don't seem to take backwards compatibility as
> > seriously.
> > They don't document the [0, 1] restriction and the behavior implemented in
> > GCC is what I saw when trying it.
> 
> Their documentation at https://clang.llvm.org/docs/LanguageExtensions.html
> is currently just
> 
>   unsigned sum = __builtin_addc(x, y, carryin, &carryout);
> 
> But a carry for a 2-ary addition is always 0 or 1, so the [0, 1] restriction
> is implicit (by the language that is used).

That is something that would need to be said explicitly, that it is undefined
behavior if it is some other value.  Like we document that e.g. __builtin_clz
is undefined behavior on 0 input.

> What do you mean by "the first additions will be less optimized"? (If you
> don't know anything about the initial carryin and the arguments, you can't
> optimize at all, AFAIK.)

I mean that if the compiler can't see it is in [0, 1], it will need to use 2
additions and or the 2 carry bits together.  But, because the ored carry bits
are in [0, 1] range, all the higher limbs could be done using addc.

If you try clang trunk with -O2
unsigned int foo (unsigned x, unsigned y, unsigned carry_in, unsigned
*carry_out) { return __builtin_addc (x, y, carry_in, carry_out); }
unsigned int bar (unsigned x, unsigned y, unsigned carry_in, unsigned
*carry_out) { if (carry_in > 1) __builtin_unreachable (); return __builtin_addc
(x, y, carry_in, carry_out); }
it shows exactly those 2 additions, rather than trying to optimize it, in both
cases.
GCC trunk emits something comparable for the first case, and 
unsigned int foo (unsigned x, unsigned y, unsigned carry_in, unsigned
*carry_out) { return __builtin_addc (x, y, carry_in, carry_out); }
you get
addb    $-1, %dl; adcl    %esi, %eax
for the main work.

Reply via email to