We use the actual access (=remote) instruction when reasoning about
accesses, except for one leftover use case of the local instruction.
This caused us to potentially ignore the dominating write if the read
and write were in a different function than the (stack) allocation.
Reported by @ye-luo
This resolves a recent regression introduced by a bug fix and allows us
to use dominating write information (formerly HasBeenWrittenTo
information) to skip potential interfering accesses.
Generally, there are two changes here:
1) If we have dominating writes they form a chain and we can look at the
least one to minimize the distance between the write and the (read)
access in question.
2) If such a least dominating write exists, we can ignore writes in
other functions as long as they cannot be reached from code between
this write and the (read) access in question.
We have all the tools available to make such queries and the positive
tests show the result. Note that the negative test from the bug fix is
still in tree and not affected.
As a side-effect, we can remove the (arbitrary) treshold now on the
number of interfering accesses since we do not iterate over dominating
ones anymore.
Recent commit introducing AA for getting underluying objects of a
pointer created an uninitialized boolean, which causes tests to fail
when built unter asan/ubsan. This initialized that variable.
This patch introduces a new AA `AAUnderlyingObjects`. It is basically like a wrapper
AA of the function `AA::getAssumedUnderlyingObjects`, but it can recursively do
query if the underlying object is an indirect access, such as a phi node or a select
instruction.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D141164
HandlePassthroughUser may sometimes create a new entry for the OffsetInfo of a
user in the OffsetInfoMap. This can invalidate outstanding references into the
map, including the one which needs to be copied into the new entry. This
produces invalid offset info that can trigger assertions.
Fixed this by not using references at this point. The bug was originally
introduced in commit ID 0dc0a441323d41b4860668f38d290579e0de130c.
Reviewed By: ronlieb
Differential Revision: https://reviews.llvm.org/D140837
AAPotentialConstantValues now works for PHI and Load by simply examinig
AAPotentialValues for the instruction itself.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D140371
Previously reverted in 8b446ea2ba39e406bcf940ea35d6efb4bb9afe95
Reapplying because this commit is NOT DEPENDENT on the reverted commit
fc21f2d7bae2e0be630470cc7ca9323ed5859892, which broke the ASAN buildbot.
See https://reviews.llvm.org/rGfc21f2d7bae2e0be630470cc7ca9323ed5859892 for
more information.
The arguments to a PHI may represent a recurrence by eventually using the output
of the PHI itself. This is now handled by checking for cycles in the control
flow. If a PHI is not in a recurrence, it is now able to report multiple offsets
instead of conservatively reporting unknown.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D138991
value() has undesired exception checking semantics and calls
__throw_bad_optional_access in libc++. Moreover, the API is unavailable without
_LIBCPP_NO_EXCEPTIONS on older Mach-O platforms (see
_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS).
This fixes check-clang-tools.
value() has undesired exception checking semantics and calls
__throw_bad_optional_access in libc++. Moreover, the API is unavailable without
_LIBCPP_NO_EXCEPTIONS on older Mach-O platforms (see
_LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS).
This fixes clang.
Previously reverted in 12696d302d146ffe616eecab3feceba9d29be2db
The arguments to a PHI may represent a recurrence by eventually using the output
of the PHI itself. This is now handled by checking for cycles in the control
flow. If a PHI is not in a recurrence, it is now able to report multiple offsets
instead of conservatively reporting unknown.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D138991
The arguments to a PHI may represent a recurrence by eventually using the output
of the PHI itself. This is now handled by checking for cycles in the control
flow. If a PHI is not in a recurrence, it is now able to report multiple offsets
instead of conservatively reporting unknown.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D138991
Even if all loads and stores are in `nosync` functions we cannot
guarantee there is no synchronization going on between them. As such, we
cannot use CFG reasoning. We could check the entire module, or, what
happens now to minimize test churn, is to check if all accesses are in
the same function that is `nosync`. A follow up will undo some of the
regressions where possible.
Similarly, reachability cannot be used to exclude an access if the
access is not known to be executed by the same thread as the given
instruction.
The OpenMP-opt test was added for the latter problem.
We had two AAs for reachability but it was very cumbersome to extend
them. We also had some fallback to use LLVM-core mechanisms and cache
the result. The new design shares the query code and interface nicely
between AAIntraFnReachability and AAInterFnReachability.
As part of the rewrite we also added the ExclusionSet to the queries.
Even if a value is for sure written we need to visit the call sites as
they might end up inside the function that reads and writes the value.
In a follow up we can introduce correct reasoning to avoid the backwards
traversal in this case and instead check if any call site between the
write and the read might reach a potential write we want to exclude.
An expression of the form `gep(base, select(pred, const1, const2))` can result
in a set of offsets instead of just one. PointerInfo can now track these sets
instead of conservatively modeling them as Unknown. In general, AAPointerInfo
now uses AAPotentialConstantValues to examine the operands of the GEP.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D138646
An expression of the form `gep(base, select(pred, const1, const2))` can result
in a set of offsets instead of just one. PointerInfo can now track these sets
instead of conservatively modeling them as Unknown. In general, AAPointerInfo
now uses AAPotentialConstantValues to examine the operands of the GEP.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D138646
Similar to dominance reasoning, we cannot use CFG reachability if the
instructions might be executed by different threads. A follow up will
improve our sensitivity for situations when it is OK to use graph
reasoning.
AAPointerInfoFloating::updateImpl
Move the member function definition out of its class before modifying it.
translateAndAddState
Split the function definition into two along the FromCallee boolean argument.
handleAccess
This should only be called when Size is not known. In other cases, replaced
with a direct call to addAccess.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D138645
If a select or PHI instruction cannot be simplified to a single value it
is often beneficial to keep the value intact rather than looking at all
the operands. The reason is that various users require a single value
and consequently can deal with the select or PHI but not multiple
operands. Recursive calls of `Attributor::getAssumedSimplifiedValues`
will be required to take such select and PHI instructions apart.
This is in preparation for future changes that introduce an actual list of
ranges per Access, to be called a RangeList.
Differential Revision: https://reviews.llvm.org/D138644
We keep loads if they feed into assumes but even if we cannot predict
their value we should delete them if the associated stores are deleted
as well. This is not perfect but prioritizes deleting stores now.
Assumptions can help us reason about memory content. This patch teaches
AAPointerInfo to reason about memory assumptions of the following form:
```
%x = load %ptr
... code not writing memory, may include branches ...
%c = %x == %val
... code not writing memory, may include branches ...
llvm.assume(%c)
```
Assumption accesses are recognized from the involved load (%x above).
Assumption accesses are treated special and neither as ordinary read or
write. We use read encoding with an extra flag. Reads are not impacting
other reads or writes. Writes could do that. We don't want assumptions
to impact other writes as they themselves only confirm a value, not
write it. So the "other" write might be required as the assumption only
confirms the effect of that write.
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated. The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.
This is part of an effort to migrate from llvm::Optional to
std::optional:
https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
This restores commit b756096b0cbef0918394851644649b3c28a886e2, which was
originally reverted in 00b09a7b18abb253d36b3d3e1c546007288f6e89.
AAPointerInfo now maintains a list of all Access objects that it owns, along
with the following maps:
- OffsetBins: OffsetAndSize -> { Access }
- InstTupleMap: RemoteI x LocalI -> Access
A RemoteI is any instruction that accesses memory. RemoteI is different from
LocalI if and only if LocalI is a call; then RemoteI is some instruction in the
callgraph starting from LocalI.
Motivation: When AAPointerInfo recomputes the offset for an instruction, it sets
the value to Unknown if the new offset is not the same as the old offset. The
instruction must now be moved from its current bin to the bin corresponding to
the new offset. This happens for example, when:
- A PHINode has operands that result in different offsets.
- The same remote inst is reachable from the same local inst via different paths
in the callgraph:
```
A (local inst)
|
B
/ \
C1 C2
\ /
D (remote inst)
```
This fixes a bug where a store is incorrectly eliminated in a lit test.
Reviewed By: jdoerfert, ye-luo
Differential Revision: https://reviews.llvm.org/D136526
This switches everything to use the memory attribute proposed in
https://discourse.llvm.org/t/rfc-unify-memory-effect-attributes/65579.
The old argmemonly, inaccessiblememonly and inaccessiblemem_or_argmemonly
attributes are dropped. The readnone, readonly and writeonly attributes
are restricted to parameters only.
The old attributes are auto-upgraded both in bitcode and IR.
The bitcode upgrade is a policy requirement that has to be retained
indefinitely. The IR upgrade is mainly there so it's not necessary
to update all tests using memory attributes in this patch, which
is already large enough. We could drop that part after migrating
tests, or retain it longer term, to make it easier to import IR
from older LLVM versions.
High-level Function/CallBase APIs like doesNotAccessMemory() or
setDoesNotAccessMemory() are mapped transparently to the memory
attribute. Code that directly manipulates attributes (e.g. via
AttributeList) on the other hand needs to switch to working with
the memory attribute instead.
Differential Revision: https://reviews.llvm.org/D135780