]> git.ipfire.org Git - thirdparty/gcc.git/commit
bitintlower: Fix up handling of SSA_NAME copies in coalescing [PR119722]
authorJakub Jelinek <jakub@redhat.com>
Sat, 12 Apr 2025 11:13:53 +0000 (13:13 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Sat, 19 Apr 2025 06:13:06 +0000 (08:13 +0200)
commit056a01f9fa85c584ed97533e75b50160d5993613
treec9b602f84255af3a2de68404c81b5557343ebce6
parent008ba21711a4aef3b6d6e7d3dbbe2f2265e29ff8
bitintlower: Fix up handling of SSA_NAME copies in coalescing [PR119722]

The following patch is miscompiled, because during the limited
SSA name coalescing the bitintlower pass does we incorrectly don't
register a conflict.
This is on
  <bb 4> [local count: 1073741824]:
  # b_17 = PHI <b_19(3), 8(2)>
  g.4_13 = g;
  _14 = g.4_13 >> 50;
  _15 = (unsigned int) _14;
  _21 = b_17;
  _16 = (unsigned int) _21;
  s_22 = _15 + _16;
  return s_22;
basic block where in the map->bitint bitmap we track 14, 17 and 19.
The build_bitint_stmt_ssa_conflicts "hook" has special code where
it tracks uses at the final statements of mergeable operations, so
e.g. the
  _16 = (unsigned int) _21;
statement is considered to be use of b_17 because _21 is not in
map->bitmap (or large_huge.m_names), i.e. is mergeable.
The problem is that build_ssa_conflict_graph has special code to handle
SSA_NAME copies and _21 = b_17; is gimple_assign_copy_p.  In such cases
it calls live_track_clear_var on the rhs1.  The problem is that
on the above bb, after we note in the _16 = (unsigned int) _21;
stmt we need b_17 the generic code makes us forget that because
of the copy statement, and then build_bitint_stmt_ssa_conflicts
ignores it completely (because _21 is large/huge bitint and is
not in map->bitint, so assumed to be handled by a later stmt in the
bb, for backwards walk like this before this one).
As the b_17 use is ignored, the coalescing thinks it can put
all of b_17, b_19 and _14 into the same partition, which is wrong,
while we can and should coalesce b_17 and b_19, _14 needs to be a different
temporary because b_17 is set before and used after _14 has been written.

The following patch fixes it by handling gimple_assign_copy_p in two
separate spots, move the generic coalesce handling of it after
build_ssa_conflict_graph (where build_ssa_conflict_graph handling
doesn't fall through to that, it does continue after the call) and
inside of build_ssa_conflict_graph it performs it too, but only if
the lhs is not mergeable large/huge bitint.

2025-04-12  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/119722
* gimple-lower-bitint.h (build_bitint_stmt_ssa_conflicts): Add
CLEAR argument.
* gimple-lower-bitint.cc (build_bitint_stmt_ssa_conflicts): Add
CLEAR argument.  Call clear on gimple_assign_copy_p rhs1 if lhs
is large/huge bitint unless lhs is not in names.
* tree-ssa-coalesce.cc (build_ssa_conflict_graph): Adjust
build_bitint_stmt_ssa_conflicts caller.  Move gimple_assign_copy_p
handling to after the build_bitint_stmt_ssa_conflicts call.

(cherry picked from commit 3f9dfb94eab1ab1bbf9a2b5e20d1f61e36516063)
gcc/gimple-lower-bitint.cc
gcc/gimple-lower-bitint.h
gcc/tree-ssa-coalesce.cc