Hi!
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).
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2026-07-28 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_BSWAP, IFN_BITREVERSE, IFN_UBSAN_CHECK_MUL and, if
bitint_big_endian, also for IFN_UBSAN_CHECK_{ADD,SUB}.
* gcc.dg/ubsan/bitint-5.c: New test.
* gcc.dg/bitint-138.c: New test.
--- gcc/gimple-lower-bitint.cc.jj 2026-07-16 09:55:30.137832903 +0200
+++ gcc/gimple-lower-bitint.cc 2026-07-28 14:13:06.606033272 +0200
@@ -7577,6 +7577,46 @@ 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_ADD:
+ case IFN_UBSAN_CHECK_SUB:
+ if (!bitint_big_endian)
+ break;
+ /* FALLTHRU */
+ case IFN_UBSAN_CHECK_MUL:
+ case IFN_BSWAP:
+ case IFN_BITREVERSE:
+ 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. */
--- gcc/testsuite/gcc.dg/ubsan/bitint-5.c.jj 2026-07-28 14:02:32.489153799
+0200
+++ gcc/testsuite/gcc.dg/ubsan/bitint-5.c 2026-07-28 14:26:10.986161540
+0200
@@ -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;
+}
--- gcc/testsuite/gcc.dg/bitint-138.c.jj 2026-07-28 14:03:58.235055737
+0200
+++ gcc/testsuite/gcc.dg/bitint-138.c 2026-07-28 14:05:23.760960486 +0200
@@ -0,0 +1,26 @@
+/* PR target/126447 */
+/* { dg-do compile { target bitint575 } } */
+/* { dg-options "-O0" } */
+
+void foo (int);
+[[gnu::returns_twice]] void bar ();
+
+unsigned _BitInt(575)
+baz ()
+{
+ unsigned _BitInt(575) w = 1;
+ bar ();
+ w = __builtin_bitreverseg (w);
+ foo (3);
+ return w;
+}
+
+unsigned _BitInt(512)
+qux ()
+{
+ unsigned _BitInt(512) w = 1;
+ bar ();
+ w = __builtin_bswapg (w);
+ foo (3);
+ return w;
+}
Jakub