tree-optimization/96881 - CD-DCE and CLOBBERs
authorRichard Biener <rguenther@suse.de>
Tue, 15 Feb 2022 12:32:22 +0000 (13:32 +0100)
committerRichard Biener <rguenther@suse.de>
Fri, 18 Feb 2022 06:58:54 +0000 (07:58 +0100)
commit422d1d378e52418d821781ad756cf3eafc3fa9a2
tree259407eee6d17a1ff8afbf0ef8c0956db9f9f6ea
parent36278f48cbc08c78e4ed588e5a049bd45fd1c55a
tree-optimization/96881 - CD-DCE and CLOBBERs

CD-DCE does not consider CLOBBERs as necessary in the attempt
to not prevent DCE of SSA defs it uses.  A side-effect of that
is that it also removes all its control dependences if they are
not made necessary by other means.  When we later try to preserve
as many CLOBBERs as possible we have to make sure we also
preserved the controlling conditions, otherwise a CLOBBER can
now appear on a path where it was not executed before, leading
to wrong code as seen in the testcase.

I've tried to continue to handle both direct and indirect
CLOBBERs optimistically, allowing CD-DCE to remove control
flow that just controls CLOBBERs but that regresses for
example the stack coalescing test g++.dg/opt/pr80032.C.
The pattern there is
  if (pred) D.2512 = CLOBBER; else D.2512 = CLOBBER;
basically we have all paths leading to the same clobber but
we could safely cut some branches which we do not realize
early enough.  This regression can be mitigated by no longer
considering direct CLOBBERs optimistically - the original
motivation for the CD-DCE handling wasn't removal of control
flow but SSA defs of the address.

Handling indirect vs. direct clobbers differently feels
somewhat wrong, still the patch goes with this solution.

2022-02-15  Richard Biener  <rguenther@suse.de>

PR tree-optimization/96881
* tree-ssa-dce.cc (mark_stmt_if_obviously_necessary): Comment
CLOBBER handling.
(control_parents_preserved_p): New function.
(eliminate_unnecessary_stmts): Check that we preserved control
parents before retaining a CLOBBER.
(perform_tree_ssa_dce): Pass down aggressive flag
to eliminate_unnecessary_stmts.

* g++.dg/torture/pr96881-1.C: New testcase.
* g++.dg/torture/pr96881-2.C: Likewise.
gcc/testsuite/g++.dg/torture/pr96881-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/pr96881-2.C [new file with mode: 0644]
gcc/tree-ssa-dce.cc