On Tue, Jul 28, 2026 at 11:55 AM Jakub Jelinek <[email protected]> wrote: > > 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?
Ok. > > 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 >
