[Attributor] Deal with shrinking dereferenceability in a loop
Summary:
If we have a loop in which the dereferenceability of a pointer decreases
we did slowly decrease it iteration by iteration, leading to a timeout.
With this patch we detect such circular reasoning and indicate a
fixpoint early.
Reviewers: uenoku, sstefan1
Subscribers: hiraditya, bollu, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D66558
llvm-svn: 369784
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index e518994..9367f48 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -1988,16 +1988,27 @@
// For now we do not try to "increase" dereferenceability due to negative
// indices as we first have to come up with code to deal with loops and
// for overflows of the dereferenceable bytes.
- if (Offset.getSExtValue() < 0)
+ int64_t OffsetSExt = Offset.getSExtValue();
+ if (OffsetSExt < 0)
Offset = 0;
T.takeAssumedDerefBytesMinimum(
- std::max(int64_t(0), DerefBytes - Offset.getSExtValue()));
+ std::max(int64_t(0), DerefBytes - OffsetSExt));
- if (!Stripped && this == &AA) {
- T.takeKnownDerefBytesMaximum(
- std::max(int64_t(0), DerefBytes - Offset.getSExtValue()));
- T.indicatePessimisticFixpoint();
+ if (this == &AA) {
+ if (!Stripped) {
+ // If nothing was stripped IR information is all we got.
+ T.takeKnownDerefBytesMaximum(
+ std::max(int64_t(0), DerefBytes - OffsetSExt));
+ T.indicatePessimisticFixpoint();
+ } else if (OffsetSExt > 0) {
+ // If something was stripped but there is circular reasoning we look
+ // for the offset. If it is positive we basically decrease the
+ // dereferenceable bytes in a circluar loop now, which will simply
+ // drive them down to the known value in a very slow way which we
+ // can accelerate.
+ T.indicatePessimisticFixpoint();
+ }
}
return T.isValidState();