[gcc r14-12783] bitintlower: Fix _BitInt SSA_NAME coalescing ICE [PR126447]

Jakub Jelinek via Gcc-cvs <[email protected]> Sat, 1 Aug 2026 10:28:59 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:0d628c7cd27ff552dafb2066f5afefd215480d84

commit r14-12783-g0d628c7cd27ff552dafb2066f5afefd215480d84
Author: Jakub Jelinek <[email protected]>
Date:   Wed Jul 29 10:04:30 2026 +0200

    bitintlower: Fix _BitInt SSA_NAME coalescing ICE [PR126447]
    
    The following testcases ICE, because the build_bitint_stmt_ssa_conflicts
    function sets for those ifns muldiv_p to true (similarly to the MULT_EXPR
    and division/modulo ones) to prevent the lhs from being mapped into
    the same underlying variable as the input operand(s).
    Now, if the lhs and at least one of the operands
    SSA_NAME_OCCURS_IN_ABNORMAL_PHI, we can trigger ICE because we fail to
    coalesce something that has to be coalesced.
    For MULT_EXPR etc. we handle this in gimple_lower_bitint, by
                        /* For multiplication and division with (ab)
                           lhs and one or both operands force the operands
                           into new SSA_NAMEs to avoid coalescing failures.  */
                        if (TREE_CODE (rhs1) == SSA_NAME
                            && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
                          {
                            first_large_huge = 0;
                            tree t = make_ssa_name (TREE_TYPE (rhs1));
                            g = gimple_build_assign (t, SSA_NAME, rhs1);
                            gsi_insert_before (&gsi, g, GSI_SAME_STMT);
                            gimple_set_location (g, loc);
                            gimple_assign_set_rhs1 (stmt, t);
                            if (rhs1 == rhs2)
                              {
                                gimple_assign_set_rhs2 (stmt, t);
                                rhs2 = t;
                              }
                            update_stmt (stmt);
                          }
    etc. a few lines above the hunk below.
    This patch just adds the same thing for the problematic internal
    fn calls (not handling that way the .MUL_OVERFLOW etc. ifns,
    because those do return COMPLEX_EXPR of BITINT_TYPE and so the
    problematic case shouldn't exist there).
    
    2026-07-29  Jakub Jelinek  <[email protected]>
    
            PR middle-end/126447
            * gimple-lower-bitint.cc (gimple_lower_bitint): For
            ifn calls with large/huge _BitInt (ab) SSA_NAME lhs if they
            have such (ab) argument too, force it into temporary SSA_NAME
            for IFN_UBSAN_CHECK_MUL.
    
            * gcc.dg/ubsan/bitint-5.c: New test.
    
    Reviewed-by: Andrea Pinski <[email protected]>
    (cherry picked from commit cd9428362b6585e77ea2a171ec030894fcfa4d1c)

Diff:
---
 gcc/gimple-lower-bitint.cc            | 33 ++++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/ubsan/bitint-5.c | 36 +++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+)

diff --git a/gcc/gimple-lower-bitint.cc b/gcc/gimple-lower-bitint.cc
index e4c9e261bd8a..d288b2d376b3 100644
--- a/gcc/gimple-lower-bitint.cc
+++ b/gcc/gimple-lower-bitint.cc
@@ -6440,6 +6440,39 @@ gimple_lower_bitint (void)
 		add_phi_arg (phi, rhs2, e3, UNKNOWN_LOCATION);
 		break;
 	      }
+	  else if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (s)
+		   && is_gimple_call (stmt)
+		   && gimple_call_internal_p (stmt))
+	    switch (gimple_call_internal_fn (stmt))
+	      {
+	      case IFN_UBSAN_CHECK_MUL:
+		for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
+		  {
+		    location_t loc = gimple_location (stmt);
+		    gsi = gsi_for_stmt (stmt);
+		    /* Similar case to multiplication/division with (ab)
+		       above for internal functions which set muldiv_p.  */
+		    tree arg = gimple_call_arg (stmt, i);
+		    if (TREE_CODE (arg) == SSA_NAME
+			&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg))
+		      {
+			first_large_huge = 0;
+			tree t = make_ssa_name (TREE_TYPE (arg));
+			g = gimple_build_assign (t, SSA_NAME, arg);
+			gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+			gimple_set_location (g, loc);
+			gimple_call_set_arg (stmt, i, t);
+			if (i == 0
+			    && gimple_call_num_args (stmt) >= 2
+			    && gimple_call_arg (stmt, 1) == arg)
+			  gimple_call_set_arg (stmt, 1, t);
+			update_stmt (stmt);
+		      }
+		  }
+		break;
+	      default:
+		break;
+	      }
 	}
       /* We need to also rewrite stores of large/huge _BitInt INTEGER_CSTs
 	 into memory.  Such functions could have no large/huge SSA_NAMEs.  */
diff --git a/gcc/testsuite/gcc.dg/ubsan/bitint-5.c b/gcc/testsuite/gcc.dg/ubsan/bitint-5.c
new file mode 100644
index 000000000000..22a613dd06a0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/bitint-5.c
@@ -0,0 +1,36 @@
+/* PR middle-end/126447 */
+/* { dg-do compile { target bitint575 } } */
+/* { dg-options "-fsanitize=signed-integer-overflow" } */
+
+void foo (int);
+[[gnu::returns_twice]] void bar ();
+
+_BitInt(575)
+baz ()
+{
+  _BitInt(575) w = 1;
+  bar ();
+  w *= 3;
+  foo (3);
+  return w;
+}
+
+_BitInt(575)
+qux ()
+{
+  _BitInt(575) w = 1;
+  bar ();
+  w += 3;
+  foo (3);
+  return w;
+}
+
+_BitInt(575)
+fred (_BitInt(575) x)
+{
+  _BitInt(575) w = 1;
+  bar ();
+  w -= x;
+  foo (3);
+  return w;
+}