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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
  Attachment #55151|0                           |1
        is obsolete|                            |

--- Comment #50 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Created attachment 55169
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55169&action=edit
gcc14-bitint-wip.patch

Update, this time with addition of libgcc _BitInt multiplication libcall (but
not really wiring it on the compiler side yet, that would be part of the new
_BitInt lowering pass).

The function currently is
void __mulbitint3 (__bitint_limb *ret, int retprec, const __bitint_limb *u, int
uprec, const __bitint_limb *v, int vprec);
which allows mixing different precisions (at compile time, or at runtime using
the bitint_reduce_prec function); while in GIMPLE before _BitInt lowering pass
MULT_EXPR
will obviously have same precision for result and both operands, the lowering
pass could
spot zero or sign extensions from narrower _BitInts for the operands, or VRP
could figure out smaller ranges of values for the operands.
Negative uprec or vprec would mean the operand is sign extended from precision
-[uv]prec, positive it is zero extended from [uv]prec.
u/v could be the same or overlapping, but as the function writes result before
consuming all inputs, doesn't allow aliasing between operands and return value.
Also, at least in the x86-64 psABI, _BitInt(N) for N < 64 is special and it
isn't expected  this function would be really used for multiplication of such
_BitInts, but of course if say multiplicating say _BitInt(512) by _Bitint(24),
it is expected the lowering pass would push those 24 bits into a 64-bit 64-bit
aligned limb and pass 24 for that operand.
For inputs it assumes bits above precision but still within a limb are
uninitialized (and so zero or sign extends when reading it), for the output it
always writes full limb (with hopefully proper zero/sign extensions).
The implemented algorith is the base school book multiplication, if really
needed, we could do Karatsuba for larger inputs.

What do you think about this API?
Shall I continue and create similar API for divmod?

Also, wonder what to do about _BitInt(N) in __builtin_mul_overflow{,_p}.  One
option would be to say that negative retprec is a request to return a nonzero
result for the overflow case, but wonder how much larger the routine would be
in that case.  Or if we
should have two, one for multiplication and one for multiplication with
overflow checking.  Yet another possibility is to do a dumb thing on the
compiler side, call the multiplication with a temporary result as large that it
would never overflow and check for the overflow on the caller side.

Reply via email to