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.