Fix SSA update when vectorisation adds a vdef to a read-only loop
authorRichard Sandiford <richard.sandiford@arm.com>
Tue, 31 Dec 2019 08:28:24 +0000 (08:28 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 31 Dec 2019 08:28:24 +0000 (08:28 +0000)
commite3969868d63b2930a0714ca3cb466831fd4be634
tree0a14f29f42cfefab7ebf765c9368be07062d29b4
parent657ccd4d5bf675a3998aa5329cad35732b6262f9
Fix SSA update when vectorisation adds a vdef to a read-only loop

This patch fixes an awkward corner case in which:

(a) we apply if-conversion to a loop;

(b) the original scalar loop doesn't have a vdef, and thus doesn't
    need a virtual phi;

(c) the vectorised main loop does need a vdef and a virtual phi (see below);

(d) we also vectorise the epilogue; and

(e) the vectorised epilogue still needs a scalar epilogue

The specific case in which (c) applies is if a read-only loop is
vectorised using IFN_LOAD_LANES, which uses clobber statements to
mark the lifetime of the temporary array.

The vectoriser relies on the SSA renamer to update virtual operands.
All would probably be well if it postponed this update until after
it had vectorised both the main loop and the epilogue loop.  However,
when vectorising the epilogue, vect_do_peeling does:

  create_lcssa_for_virtual_phi (loop);
  update_ssa (TODO_update_ssa_only_virtuals);

(with "loop" in this case being the to-be-vectorised epilogue loop).
So the vectoriser puts the virtual operand into SSA form for the
vectorised main loop as a separate step, during the early stages
of vectorising the epilogue.

I wasn't sure at first why that update_ssa was there.  It looked
initially like it was related to create_lcssa_for_virtual_phi,
which seemed strange when create_lcssa_for_virtual_phi keeps the
SSA form up-to-date.  But before r241099 it had the following comment,
which AFAICT is still the reason:

  /* We might have a queued need to update virtual SSA form.  As we
     delete the update SSA machinery below after doing a regular
     incremental SSA update during loop copying make sure we don't
     lose that fact.
     ???  Needing to update virtual SSA form by renaming is unfortunate
     but not all of the vectorizer code inserting new loads / stores
     properly assigns virtual operands to those statements.  */

The patch restores that comment since IMO it's helpful.

(a), (d) and (e) mean that we copy the original un-if-converted scalar
loop to act as the scalar epilogue.  The update_ssa above means that this
copying needs to cope with any new virtual SSA names in the main loop.
The code to do that (reasonably) assumed that one of two things was true:

(1) the scalar loop and the vector loops don't have vdefs, and so no
    virtual operand update is needed.  The definition that applies
    on entry to the loops is the same in all cases.

(2) the scalar loop and the vector loops have virtual phis, and so --
    after applying create_lcssa_for_virtual_phi on the to-be-vectorised
    epilogue loop -- the virtual operand update can be handled in the
    same way as for normal SSA names.

But (b) and (c) together mean that the scalar loop and the
still-to-be-vectorised epilogue loop have no virtual phi that (2)
can use.  We'd therefore keep the original vuses when duplicating,
rather than updating them to the definition that applies on exit
from the epilogue loop.  (Since the epilogue is still unvectorised
and has no vdefs, the definition that applies on exit is the same
as the one that applies on entry.)

This patch therefore adds a third case: the scalar loop and
to-be-vectorised epilogue have no virtual defs, but the main loop does.

2019-12-31  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
* tree-vect-loop-manip.c (create_lcssa_for_virtual_phi): Return
the incoming virtual operand definition.
(vect_do_peeling): When vectorizing an epilogue loop, handle the
case in which the main loop has a virtual phi and the epilogue
and scalar loops don't.  Restore an earlier comment about the
update_ssa call.

gcc/testsuite/
* gcc.dg/vect/vect-epilogues-2.c: New test.

From-SVN: r279802
gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/vect-epilogues-2.c [new file with mode: 0644]
gcc/tree-vect-loop-manip.c