]> git.ipfire.org Git - thirdparty/gcc.git/commit
bitint: Fix up INTEGER_CST PHI handling [PR121413]
authorJakub Jelinek <jakub@redhat.com>
Wed, 6 Aug 2025 09:30:08 +0000 (11:30 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 6 Aug 2025 09:30:08 +0000 (11:30 +0200)
commit70aff5112ec25f2391d8048d8c7994160d3cb008
tree56519c70ea2cc9fba8eca1a86945f4ca0250e6e0
parentd175a6b119b8ab177ab9d9fb81dcac1794d18ad6
bitint: Fix up INTEGER_CST PHI handling [PR121413]

The following testcase is miscompiled on aarch64-linux.
The problem is in the optimization to shorten large constants
in PHI arguments.
In a couple of places during bitint lowering we compute
minimal precision of constant and if it is significantly
smaller than the precision of the type, store smaller constant
in memory and extend it at runtime (zero or all ones).
Now, in most places that works fine, we handle the stored number
of limbs by loading them from memory and then the rest is
extended.  In the PHI INTEGER_CST argument handling we do
it differently, we don't form there any loops (because we
insert stmt sequences on the edges).
The problem is that we copy the whole _BitInt variable from
memory to the PHI VAR_DECL + initialize the rest to = {} or
memset to -1.  It has
min_prec = CEIL (min_prec, limb_prec) * limb_prec;
precision, so e.g. on x86_64 there is no padding and it works
just fine.  But on aarch64 which has abi_limb_mode TImode
and limb_mode DImode it doesn't in some cases.
In the testcase the constant has 408 bits min precision, rounded up
to limb_prec (64) is 448, i.e. 7 limbs.  But aarch64 with TImode
abi_limb_mode will actually allocate 8 limbs and the most significant
limb is solely padding.  As we want to extend the constant with all
ones, copying the padding (from memory, so 0s) will result in
64 0 bits where 1 bits were needed.

The following patch fixes it by detecting this case and setting
min_prec to a multiple of abi limb precision so that it has
no padding.

2025-08-06  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/121413
* gimple-lower-bitint.cc (abi_limb_prec): New variable
(bitint_precision_kind): Initialize it.
(gimple_lower_bitint): Clear it at the start.  For
min_prec > limb_prec descreased precision vars for
INTEGER_CST PHI arguments ensure min_prec is either
prec or multiple of abi_limb_prec.

* gcc.dg/torture/bitint-85.c: New test.
gcc/gimple-lower-bitint.cc
gcc/testsuite/gcc.dg/torture/bitint-85.c [new file with mode: 0644]