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

Reply via email to