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

--- Comment #45 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Let's consider some simple testcase (where one doesn't really mix different
_BitInt sizes etc.).
_BitInt(512)
foo (_BitInt(512) a, _BitInt(512) b, _BitInt(512) c, _BitInt(512) d)
{
  return (a + b) - (c + d);
}
With the patch, this now ICEs during expansion, because while we can handle
copying of even the larger _BitInt vars, we don't handle (nor plan to) +/- etc.
during expansion for that, it would be in the earlier lowering pass.
If I'd emit straight line code here, I suppose I could use
BIT_FIELD_REFs/BIT_INSERT_EXPRs, but if I want loopy code, as you wrote perhaps
ARRAY_REF on VCE could work fine for the input operands, but dunno what to use
for the
result of the operation, forcing it into a VAR_DECL I'm afraid will mean we
can't coalesce it much, the above would force the 2 + results and 1 - result
into VAR_DECLs.
Could we e.g. allow BIT_INSERT_EXPRs or have some new ref for this purpose to
update a single limb in a BITTYPE_INT SSA_NAME?

Now, looking what we do right now, detailed expand dump before emergency dump
shows:
Partition map

Partition 0 (_1 - 1 )
Partition 1 (_2 - 2 )
Partition 2 (_3 - 3 )
Partition 3 (a_4(D) - 4 )
Partition 4 (b_5(D) - 5 )
Partition 5 (c_6(D) - 6 )
Partition 6 (d_7(D) - 7 )
which I believe means it didn't actually coalesce anything at all.  For the
larger BITINT_TYPEs it will be very much desirable to coalesce as much as
possible, given that none of the default def SSA_NAMEs are really use I'd think
ideally we'd do
a += b
c += d
result = a - c

For at least multiplication/division and I assume conversions to/from floating
point (and decimal), we'll need some library calls.
One question is what ABI to use for them, whether to e.g. pass pointer to the
limbs
(and when -fbuilding-libgcc predefine macros on what mode is the limb mode,
whether the limbs are ordered from least significant to most or vice versa,
etc.) and in addition to that precision in bits for each argument and whether
it is zero or sign extended from that, so that we could e.g. handle more
efficiently
_BitInt(16384)
foo (unsigned _BitInt(2048) a, _BitInt(1024) b)
{
  return (_BitInt(16384) a) * b;
}
by passing e.g. _mulwhatever (&res, 16384, &a, 2048, &b, -1024)
where -1024 would mean 1024 bits sign extended, 2048 2048 bits zero extended,
result
is 16384 bits.  And for GIMPLE a question is how to express it before
expansion, whether
we use some ifn that is then lowered.

Reply via email to