https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126262
--- Comment #4 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The releases/gcc-16 branch has been updated by Jakub Jelinek <[email protected]>: https://gcc.gnu.org/g:7fd08ffb1536e6e81bd3ea38e59bb39c55e84899 commit r16-9297-g7fd08ffb1536e6e81bd3ea38e59bb39c55e84899 Author: Jakub Jelinek <[email protected]> Date: Thu Jul 16 09:55:37 2026 +0200 bitintlower: Avoid coalescing lhs with operands for .MUL_OVERFLOW [PR126262] 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. 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. Reviewed-by: Richard Biener <[email protected]> (cherry picked from commit b032f71e16603f974b4cbc3d87752d21f43980af)
