On Thu, 16 Jul 2026, Jakub Jelinek wrote: > Hi! > > We need to avoid overlap between the lhs and input operands of __mulbitint3 > and __divmodbitint4. This is done in build_bitint_stmt_ssa_conflicts, when > muldiv_p is set, we call use on all the SSA use operands (including operands > of stmts on worklist) first and def on the lhs at the end, while for > !muldiv_p, at least for stmts with a single lhs we call def first and then > all the use calls. For MULT_EXPR etc. we already handle it: > case MULT_EXPR: > case TRUNC_DIV_EXPR: > case EXACT_DIV_EXPR: > case TRUNC_MOD_EXPR: > muldiv_p = true; > Now, for the IFN_*_OVERFLOW, we handle it for bitint_big_endian only > currently, on big endian there is a problem that if the sizes don't match > exactly, even in order updates of the limbs can clobber stuff. > But, for IFN_MUL_OVERFLOW and IFN_UBSAN_CHECK_MUL, we actually use > __mulbitint3 libgcc call and that function really can't be called with > overlapping destination and inputs, because it traverses the inputs multiple > times while writing destination one by one (and it intentionally doesn't > allocate memory for temporaries). > > So, the following patch fixes it by making IFN_MUL_OVERFLOW and > IFN_UBSAN_CHECK_MUL calls be always handled as muldiv_p. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk and 14+?
OK. Thanks, Richard. > 2026-07-16 Jakub Jelinek <[email protected]> > > PR tree-optimization/126262 > * gimple-lower-bitint.cc (build_bitint_stmt_ssa_conflicts): Treat > IFN_MUL_OVERFLOW and IFN_UBSAN_CHECK_MUL like IFN_BSWAP, regardless > of bitint_big_endian. > > * gcc.dg/torture/bitint-102.c: New test. > > --- gcc/gimple-lower-bitint.cc.jj 2026-07-14 10:39:46.547982133 +0200 > +++ gcc/gimple-lower-bitint.cc 2026-07-15 17:51:01.922732017 +0200 > @@ -7028,8 +7028,6 @@ build_bitint_stmt_ssa_conflicts (gimple > case IFN_SUB_OVERFLOW: > case IFN_UBSAN_CHECK_ADD: > case IFN_UBSAN_CHECK_SUB: > - case IFN_MUL_OVERFLOW: > - case IFN_UBSAN_CHECK_MUL: > if (bitint_big_endian) > { > lhs = gimple_call_lhs (stmt); > @@ -7037,6 +7035,8 @@ build_bitint_stmt_ssa_conflicts (gimple > muldiv_p = true; > } > break; > + case IFN_MUL_OVERFLOW: > + case IFN_UBSAN_CHECK_MUL: > case IFN_BSWAP: > case IFN_BITREVERSE: > lhs = gimple_call_lhs (stmt); > --- gcc/testsuite/gcc.dg/torture/bitint-102.c.jj 2026-07-15 > 18:43:06.967455017 +0200 > +++ gcc/testsuite/gcc.dg/torture/bitint-102.c 2026-07-15 18:42:51.156653874 > +0200 > @@ -0,0 +1,33 @@ > +/* PR tree-optimization/126262 */ > +/* { dg-do run { target bitint } } */ > +/* { dg-options "-std=gnu23" } */ > + > +#if __BITINT_MAXWIDTH__ >= 1024 > +typedef unsigned _BitInt (512) A; > +typedef _BitInt (1024) B; > + > +[[gnu::noipa]] int > +foo (signed char x, A y) > +{ > + B b = -(B) y; > + A c; > + if (__builtin_mul_overflow (1, b, &c)) > + c = 42; > + B f; > + if (__builtin_mul_overflow (x, 9, &f)) > + f = 42; > + int i; > + if (__builtin_mul_overflow (f, 1, &i)) > + i = 42; > + return c + i; > +} > +#endif > + > +int > +main () > +{ > +#if __BITINT_MAXWIDTH__ >= 1024 > + if (foo (1, -2) != 51) > + __builtin_abort (); > +#endif > +} > > Jakub > > -- Richard Biener <[email protected]> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Jochen Jaser, Andrew McDonald, Abhinav Puri; (HRB 36809, AG Nuernberg)
