https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106922

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
Created attachment 53577
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53577&action=edit
testcase for missed PRE on trunk

Here's one.

So the issue is that PRE EXP_GEN now contains

exp_gen[10] := {
{component_ref<m_initialized>,mem_ref<0B>,addr_expr<&external>}@.MEM_31 (0009)
}

for the block

<bb 10> [local count: 97603128]:
# .MEM_31 = VDEF <.MEM_55>
internal ={v} {CLOBBER};
# VUSE <.MEM_32>
_10 = MEM[(struct optional_base *)&external].m_initialized;
if (_10 != 0)

instead of the one with last_vuse .MEM_45.  That in turn causes
prune_clobbered_mems to prune the expression from ANTIC_OUT of BB 9 which
has a 9->10 edge removing the incentive to perform FRE on this value inside
the loop.  prune_clobbered_mems does this because

          if (ref->vuse)
            {
              gimple *def_stmt = SSA_NAME_DEF_STMT (ref->vuse);
              if (!gimple_nop_p (def_stmt)
                  && ((gimple_bb (def_stmt) != block
                       && !dominated_by_p (CDI_DOMINATORS,
                                           block, gimple_bb (def_stmt)))
                      || (gimple_bb (def_stmt) == block
                          && value_dies_in_block_x (expr, block))))
                to_remove = i;

where block == BB9 so the dominance test fails.  The dominance test should
be redundant (unless we have translated something over a backedge!?) but
it really shows the issue that we fail to record the memory expression
with the correct VUSE into EXP_GEN and fail to adjust the VUSE when
translating from ANTIC_OUT to ANTIC_IN as well.  When we'd do all this
"correctly", then we'd get a) a ton more hashtable entries with questionable
value, b) the dominance test will never fail.

By that reasoning a cheaper fix should be to instead perform the
value_dies_in_block_x when a dominance check cannot elide it.

There's a possible latent issue with virtual operands PHI translation
over backedges then though.  The safest thing would be to eventually
force a set of the virtual operand when any virtual PHI is on the
edge we are translating over - we are actually doing this but the
no-PHI-nodes optimization in phi_translate_set defeats the intent of
adjusting to BB_LIVE_VOP_ON_EXIT that translate_vuse_through_block
performs and its simple check of BB equality means we don't fixup later
either.

Fixing that spot in the simplistic way as well (rather than consistently
handling the virtual operand everywhere) fixes the observed bogus
diagnostic.

Reply via email to