1. Reapply [LVI] Normalize pointer behavior (details)
  2. [ELF] Fix stack-use-after-scope after D69592 and 69650 (details)
Commit 885a05f48a5d320946c89590b73a764e5884fe4f by nikita.ppv
Reapply [LVI] Normalize pointer behavior
Fix cache invalidation by not guarding the dereferenced pointer cache
erasure by SeenBlocks. SeenBlocks is only populated when actually
caching a value in the block, which doesn't necessarily have to happen
just because dereferenced pointers were calculated.
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 change
not fully NFC, because we can now fold terminator icmps based on the
dereferencability information in the same block. This is the reason why
I changed one JumpThreading test
(it would optimize the condition away without the change).
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:
The file was modifiedllvm/lib/Analysis/LazyValueInfo.cpp
The file was modifiedllvm/test/Transforms/JumpThreading/combine-metadata.ll
Commit 5b47efa20e0c482a60af5fea8dd7e3fae94c1a7e by maskray
[ELF] Fix stack-use-after-scope after D69592 and 69650
The file was modifiedlld/ELF/Relocations.cpp