SuccessChanges

Summary

  1. [NFCI][Local] Rewrite EliminateDuplicatePHINodes to optionally check hashing invariants (details)
  2. [NFC][Local] EliminateDuplicatePHINodes(): add STATISTIC() (details)
  3. Reapply [LVI] Normalize pointer behavior (details)
Commit 961483a5ea7c0e628c025187287d1658457ffcb3 by lebedev.ri
[NFCI][Local] Rewrite EliminateDuplicatePHINodes to optionally check hashing invariants

EarlyCSE has a mode to verify the invariant that hash equality equals
key equality, but EliminateDuplicatePHINodes() doesn't.

I've verified that this would have caught the stage2-stage3 mismatches
5ec2b757cc7d37ff0d03b36ee863b0962fe78108 revert has fixed,
that were introduced last time in 3e69871ab5a66fb55913a2a2f5e7f5b42899a4c9.
The file was modifiedllvm/lib/Transforms/Utils/Local.cpp (diff)
Commit 1dcb936cf693b7f7abd271edc27df13425ebaac0 by lebedev.ri
[NFC][Local] EliminateDuplicatePHINodes(): add STATISTIC()
The file was modifiedllvm/lib/Transforms/Utils/Local.cpp (diff)
Commit 6d88f6efd44852b995de3a1620ea67b6381c1ad9 by nikita.ppv
Reapply [LVI] Normalize pointer behavior

This got reverted because a dependency was reverted. It has since
been reapplied, so reapply this as well.

-----

Related to D69686. As noted there, LVI currently behaves differently
for integer and pointer values: For integers, the block value is always
valid inside the basic block, while for pointers it is only valid at
the end of the basic block. I believe the integer behavior is the
correct one, and CVP relies on it via its getConstantRange() uses.

The reason for the special pointer behavior is that LVI checks whether
a pointer is dereferenced in a given basic block and marks it as
non-null in that case. Of course, this information is valid only after
the dereferencing instruction, or in conservative approximation,
at the end of the block.

This patch changes the treatment of dereferencability: Instead of
including it inside the block value, we instead treat it as something
similar to an assume (it essentially is a non-nullness assume) and
incorporate this information in intersectAssumeOrGuardBlockValueConstantRange()
if the context instruction is the terminator of the basic block.
This happens either when determining an edge-value internally in LVI,
or when a terminator was explicitly passed to getValueAt(). The latter
case makes this more powerful than the previous implementation as
a side-effect, and this does actually seem benefitial in practice.

Of course, we do not want to recompute dereferencability on each
intersectAssume call, so we need a new cache for this. The
dereferencability analysis requires walking the entire basic block
and computing underlying objects of all memory operands. This was
previously done separately for each queried pointer value. In the
new implementation (both because this makes the caching simpler,
and because it is faster), I instead only walk the full BB once and
cache all the dereferenced pointers. So the traversal is now performed
only once per BB, instead of once per queried pointer value.

I think the overall model now makes more sense than before, and there
will be no more pitfalls due to differing integer/pointer behavior.

Differential Revision: https://reviews.llvm.org/D69914
The file was modifiedllvm/lib/Analysis/LazyValueInfo.cpp (diff)
The file was modifiedllvm/test/Transforms/CorrelatedValuePropagation/non-null.ll (diff)