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.

Reply via email to