https://gcc.gnu.org/g:d175a6b119b8ab177ab9d9fb81dcac1794d18ad6
commit r16-3033-gd175a6b119b8ab177ab9d9fb81dcac1794d18ad6 Author: Jakub Jelinek <ja...@redhat.com> Date: Wed Aug 6 11:28:37 2025 +0200 bitint: Fix up handling of uninitialized mul/div/float cast operands [PR121127] handle_operand_addr (used for the cases where we use libgcc APIs, so multiplication, division, modulo, casts of _BitInt to float/dfp) when it sees default definition of an SSA_NAME which is not PARM_DECL (i.e. uninitialized one) just allocates single uninitialized limb, there is no need to waste more memory on it, it can just tell libgcc that it has 64-bit precision, not say 1024 bit etc. Unfortunately, doing this runs into some asserts when we have a narrowing cast of the uninitialized SSA_NAME (but still large/huge _BitInt). The following patch fixes that by using a magic value in *prec_stored for the uninitialized cases (0) and just don't do any *prec tweaks for narrowing casts from that. precs still needs to be maintained as before, that one is used for big endian adjustment. 2025-08-06 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/121127 * gimple-lower-bitint.cc (bitint_large_huge::handle_operand_addr): For uninitialized SSA_NAME, set *prec_stored to 0 rather than *prec. Handle that case in narrowing casts. If prec_stored is non-NULL, set *prec_stored to prec_stored_val. * gcc.dg/bitint-125.c: New test. Diff: --- gcc/gimple-lower-bitint.cc | 15 ++++++++++++--- gcc/testsuite/gcc.dg/bitint-125.c | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc index 8fb7a604591d..ff5b12c6f5c4 100644 --- a/gcc/gimple-lower-bitint.cc +++ b/gcc/gimple-lower-bitint.cc @@ -2373,7 +2373,7 @@ range_to_prec (tree op, gimple *stmt) from that precision, if it is negative, the operand is sign-extended from -*PREC. If PREC_STORED is NULL, it is the toplevel call, otherwise *PREC_STORED is prec from the innermost call without - range optimizations. */ + range optimizations (0 for uninitialized SSA_NAME). */ tree bitint_large_huge::handle_operand_addr (tree op, gimple *stmt, @@ -2481,7 +2481,7 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt, *prec = TYPE_UNSIGNED (TREE_TYPE (op)) ? limb_prec : -limb_prec; precs = *prec; if (prec_stored) - *prec_stored = precs; + *prec_stored = 0; tree var = create_tmp_var (m_limb_type); TREE_ADDRESSABLE (var) = 1; ret = build_fold_addr_expr (var); @@ -2510,6 +2510,13 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt, int prec_stored_val = 0; ret = handle_operand_addr (rhs1, g, &prec_stored_val, prec); precs = prec_stored_val; + if (prec_stored) + *prec_stored = prec_stored_val; + if (precs == 0) + { + gcc_assert (*prec == limb_prec || *prec == -limb_prec); + precs = *prec; + } if (TYPE_PRECISION (lhs_type) > TYPE_PRECISION (rhs_type)) { if (TYPE_UNSIGNED (lhs_type) @@ -2518,7 +2525,9 @@ bitint_large_huge::handle_operand_addr (tree op, gimple *stmt, } else { - if (*prec > 0 && *prec < TYPE_PRECISION (lhs_type)) + if (prec_stored_val == 0) + /* Non-widening cast of uninitialized value. */; + else if (*prec > 0 && *prec < TYPE_PRECISION (lhs_type)) ; else if (TYPE_UNSIGNED (lhs_type)) { diff --git a/gcc/testsuite/gcc.dg/bitint-125.c b/gcc/testsuite/gcc.dg/bitint-125.c new file mode 100644 index 000000000000..5ef0e327d54f --- /dev/null +++ b/gcc/testsuite/gcc.dg/bitint-125.c @@ -0,0 +1,15 @@ +/* PR tree-optimization/121127 */ +/* { dg-do compile { target bitint } } */ +/* { dg-options "-O2 -w" } */ + +#if __BITINT_MAXWIDTH__ >= 576 +_BitInt(575) +foo (void) +{ + _BitInt(576) d; + _BitInt(575) e = d * 42wb; + return e; +} +#else +int i; +#endif