https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119808
--- Comment #5 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Jakub Jelinek <ja...@gcc.gnu.org>: https://gcc.gnu.org/g:5a48e7732d6aa0aaf12b508fa640125e6c4d14b9 commit r15-9516-g5a48e7732d6aa0aaf12b508fa640125e6c4d14b9 Author: Jakub Jelinek <ja...@redhat.com> Date: Wed Apr 16 09:11:06 2025 +0200 bitintlower: Fix interaction of gimple_assign_copy_p stmts vs. has_single_use [PR119808] The following testcase is miscompiled, because we emit a CLOBBER in a place where it shouldn't be emitted. Before lowering we have: b_5 = 0; b.0_6 = b_5; b.1_1 = (unsigned _BitInt(129)) b.0_6; ... <retval> = b_5; The bitint coalescing assigns the same partition/underlying variable for both b_5 and b.0_6 (possible because there is a copy assignment) and of course a different one for b.1_1 (and other SSA_NAMEs in between). This is -O0 so stmts aren't DCEd and aren't propagated that much etc. It is -O0 so we also don't try to optimize and omit some names from m_names and handle multiple stmts at once, so the expansion emits essentially bitint.4 = {}; bitint.4 = bitint.4; bitint.2 = cast of bitint.4; bitint.4 = CLOBBER; ... <retval> = bitint.4; and the CLOBBER is the problem because bitint.4 is still live afterwards. We emit the clobbers to improve code generation, but do it only for (initially) has_single_use SSA_NAMEs (remembered in m_single_use_names) being used, if they don't have the same partition on the lhs and a few other conditions. The problem above is that b.0_6 which is used in the cast has_single_use and so was in m_single_use_names bitmask and the lhs in that case is bitint.2, so a different partition. But there is gimple_assign_copy_p with SSA_NAME rhs1 and the partitioning special cases those and while b.0_6 is single use, b_5 has multiple uses. I believe this ought to be a problem solely in the case of such copy stmts and its special case by the partitioning, if instead of b.0_6 = b_5; there would be b.0_6 = b_5 + 1; or whatever other stmts that performs or may perform changes on the value, partitioning couldn't assign the same partition to b.0_6 and b_5 if b_5 is used later, it couldn't have two different (or potentially different) values in the same bitint.N var. With copy that is possible though. So the following patch fixes it by being more careful when we set m_single_use_names, don't set it if it is a has_single_use SSA_NAME but SSA_NAME_DEF_STMT of it is a copy stmt with SSA_NAME rhs1 and that rhs1 doesn't have single use, or has_single_use but SSA_NAME_DEF_STMT of it is a copy stmt etc. Just to make sure it doesn't change code generation too much, I've gathered statistics how many times if (m_first && m_single_use_names && m_vars[p] != m_lhs && m_after_stmt && bitmap_bit_p (m_single_use_names, SSA_NAME_VERSION (op))) { tree clobber = build_clobber (TREE_TYPE (m_vars[p]), CLOBBER_STORAGE_END); g = gimple_build_assign (m_vars[p], clobber); gimple_stmt_iterator gsi = gsi_for_stmt (m_after_stmt); gsi_insert_after (&gsi, g, GSI_SAME_STMT); } emits a clobber on make check-gcc GCC_TEST_RUN_EXPENSIVE=1 RUNTESTFLAGS="--target_board=unix\{-m64,-m32\} GCC_TEST_RUN_EXPENSIVE=1 dg.exp='*bitint* pr112673.c builtin-stdc-bit-*.c pr112566-2.c pr112511.c pr116588.c pr116003.c pr113693.c pr113602.c flex-array-counted-by-7.c' dg-torture.exp='*bitint* pr116480-2.c pr114312.c pr114121.c' dfp.exp=*bitint* i386.exp='pr118017.c pr117946.c apx-ndd-x32-2a.c' vect.exp='vect-early-break_99-pr113287.c' tree-ssa.exp=pr113735.c" and before this patch it was 41010 clobbers and after it is 40968, so difference is 42 clobbers, 0.1% fewer. 2025-04-16 Jakub Jelinek <ja...@redhat.com> PR middle-end/119808 * gimple-lower-bitint.cc (gimple_lower_bitint): Don't set m_single_use_names bits for SSA_NAMEs which have single use but their SSA_NAME_DEF_STMT is a copy from another SSA_NAME which doesn't have a single use, or single use which is such a copy etc. * gcc.dg/bitint-121.c: New test.