Page MenuHomePhabricator

File Metadata

Author
spatel
Created
Feb 1 2017, 10:11 AM

badass2.patch

Index: include/llvm/Analysis/AssumptionCache.h
===================================================================
--- include/llvm/Analysis/AssumptionCache.h (revision 293646)
+++ include/llvm/Analysis/AssumptionCache.h (working copy)
@@ -106,11 +106,13 @@
/// \brief Clear the cache of @llvm.assume intrinsics for a function.
///
- /// It will be re-scanned the next time it is requested.
- void clear() {
+ /// It will be re-scanned the next time it is requested unless ShouldNotRescan
+ /// is set to true to indicate an irrecoverable problem.
+ void clear(bool ShouldNotRescan = false) {
AssumeHandles.clear();
AffectedValues.clear();
- Scanned = false;
+ if (!ShouldNotRescan)
+ Scanned = false;
}
/// \brief Access the list of assumption handles currently tracked for this
Index: lib/Analysis/ValueTracking.cpp
===================================================================
--- lib/Analysis/ValueTracking.cpp (revision 293646)
+++ lib/Analysis/ValueTracking.cpp (working copy)
@@ -528,7 +528,7 @@
// Note that the patterns below need to be kept in sync with the code
// in AssumptionCache::updateAffectedValues.
-
+ bool ChangedFromAssume = false;
for (auto &AssumeVH : Q.AC->assumptionsFor(V)) {
if (!AssumeVH)
continue;
@@ -579,6 +579,7 @@
computeKnownBits(A, RHSKnownZero, RHSKnownOne, Depth+1, Query(Q, I));
KnownZero |= RHSKnownZero;
KnownOne |= RHSKnownOne;
+ ChangedFromAssume = true;
// assume(v & b = a)
} else if (match(Arg,
m_c_ICmp(Pred, m_c_And(m_V, m_Value(B)), m_Value(A))) &&
@@ -593,6 +594,7 @@
// known bits from the RHS to V.
KnownZero |= RHSKnownZero & MaskKnownOne;
KnownOne |= RHSKnownOne & MaskKnownOne;
+ ChangedFromAssume = true;
// assume(~(v & b) = a)
} else if (match(Arg, m_c_ICmp(Pred, m_Not(m_c_And(m_V, m_Value(B))),
m_Value(A))) &&
@@ -607,6 +609,7 @@
// inverted known bits from the RHS to V.
KnownZero |= RHSKnownOne & MaskKnownOne;
KnownOne |= RHSKnownZero & MaskKnownOne;
+ ChangedFromAssume = true;
// assume(v | b = a)
} else if (match(Arg,
m_c_ICmp(Pred, m_c_Or(m_V, m_Value(B)), m_Value(A))) &&
@@ -621,6 +624,7 @@
// bits from the RHS to V.
KnownZero |= RHSKnownZero & BKnownZero;
KnownOne |= RHSKnownOne & BKnownZero;
+ ChangedFromAssume = true;
// assume(~(v | b) = a)
} else if (match(Arg, m_c_ICmp(Pred, m_Not(m_c_Or(m_V, m_Value(B))),
m_Value(A))) &&
@@ -635,6 +639,7 @@
// inverted known bits from the RHS to V.
KnownZero |= RHSKnownOne & BKnownZero;
KnownOne |= RHSKnownZero & BKnownZero;
+ ChangedFromAssume = true;
// assume(v ^ b = a)
} else if (match(Arg,
m_c_ICmp(Pred, m_c_Xor(m_V, m_Value(B)), m_Value(A))) &&
@@ -652,6 +657,7 @@
KnownOne |= RHSKnownOne & BKnownZero;
KnownZero |= RHSKnownOne & BKnownOne;
KnownOne |= RHSKnownZero & BKnownOne;
+ ChangedFromAssume = true;
// assume(~(v ^ b) = a)
} else if (match(Arg, m_c_ICmp(Pred, m_Not(m_c_Xor(m_V, m_Value(B))),
m_Value(A))) &&
@@ -669,6 +675,7 @@
KnownOne |= RHSKnownZero & BKnownZero;
KnownZero |= RHSKnownZero & BKnownOne;
KnownOne |= RHSKnownOne & BKnownOne;
+ ChangedFromAssume = true;
// assume(v << c = a)
} else if (match(Arg, m_c_ICmp(Pred, m_Shl(m_V, m_ConstantInt(C)),
m_Value(A))) &&
@@ -680,6 +687,7 @@
// bits in V shifted to the right by C.
KnownZero |= RHSKnownZero.lshr(C->getZExtValue());
KnownOne |= RHSKnownOne.lshr(C->getZExtValue());
+ ChangedFromAssume = true;
// assume(~(v << c) = a)
} else if (match(Arg, m_c_ICmp(Pred, m_Not(m_Shl(m_V, m_ConstantInt(C))),
m_Value(A))) &&
@@ -691,6 +699,7 @@
// to known bits in V shifted to the right by C.
KnownZero |= RHSKnownOne.lshr(C->getZExtValue());
KnownOne |= RHSKnownZero.lshr(C->getZExtValue());
+ ChangedFromAssume = true;
// assume(v >> c = a)
} else if (match(Arg,
m_c_ICmp(Pred, m_CombineOr(m_LShr(m_V, m_ConstantInt(C)),
@@ -704,6 +713,7 @@
// bits in V shifted to the right by C.
KnownZero |= RHSKnownZero << C->getZExtValue();
KnownOne |= RHSKnownOne << C->getZExtValue();
+ ChangedFromAssume = true;
// assume(~(v >> c) = a)
} else if (match(Arg, m_c_ICmp(Pred, m_Not(m_CombineOr(
m_LShr(m_V, m_ConstantInt(C)),
@@ -717,6 +727,7 @@
// to known bits in V shifted to the right by C.
KnownZero |= RHSKnownOne << C->getZExtValue();
KnownOne |= RHSKnownZero << C->getZExtValue();
+ ChangedFromAssume = true;
// assume(v >=_s c) where c is non-negative
} else if (match(Arg, m_ICmp(Pred, m_V, m_Value(A))) &&
Pred == ICmpInst::ICMP_SGE &&
@@ -727,6 +738,7 @@
if (RHSKnownZero.isNegative()) {
// We know that the sign bit is zero.
KnownZero |= APInt::getSignBit(BitWidth);
+ ChangedFromAssume = true;
}
// assume(v >_s c) where c is at least -1.
} else if (match(Arg, m_ICmp(Pred, m_V, m_Value(A))) &&
@@ -738,6 +750,7 @@
if (RHSKnownOne.isAllOnesValue() || RHSKnownZero.isNegative()) {
// We know that the sign bit is zero.
KnownZero |= APInt::getSignBit(BitWidth);
+ ChangedFromAssume = true;
}
// assume(v <=_s c) where c is negative
} else if (match(Arg, m_ICmp(Pred, m_V, m_Value(A))) &&
@@ -749,6 +762,7 @@
if (RHSKnownOne.isNegative()) {
// We know that the sign bit is one.
KnownOne |= APInt::getSignBit(BitWidth);
+ ChangedFromAssume = true;
}
// assume(v <_s c) where c is non-positive
} else if (match(Arg, m_ICmp(Pred, m_V, m_Value(A))) &&
@@ -760,6 +774,7 @@
if (RHSKnownZero.isAllOnesValue() || RHSKnownOne.isNegative()) {
// We know that the sign bit is one.
KnownOne |= APInt::getSignBit(BitWidth);
+ ChangedFromAssume = true;
}
// assume(v <=_u c)
} else if (match(Arg, m_ICmp(Pred, m_V, m_Value(A))) &&
@@ -771,6 +786,7 @@
// Whatever high bits in c are zero are known to be zero.
KnownZero |=
APInt::getHighBitsSet(BitWidth, RHSKnownZero.countLeadingOnes());
+ ChangedFromAssume = true;
// assume(v <_u c)
} else if (match(Arg, m_ICmp(Pred, m_V, m_Value(A))) &&
Pred == ICmpInst::ICMP_ULT &&
@@ -786,8 +802,21 @@
else
KnownZero |=
APInt::getHighBitsSet(BitWidth, RHSKnownZero.countLeadingOnes());
+ ChangedFromAssume = true;
}
}
+
+ // If bits known from assumptions conflict with each other or previous known
+ // bits, then we have a logical fallacy. This should only happen when a
+ // program has undefined behavior. We can't assert/crash, so clear out the
+ // knowledge and hope for the best.
+ if (ChangedFromAssume && (KnownZero & KnownOne) != 0) {
+ KnownZero.clearAllBits();
+ KnownOne.clearAllBits();
+ // The cache is irreparably polluted. Don't let future queries repopulate
+ // it and risk passing bad knowledge out.
+ Q.AC->clear(true);
+ }
}
// Compute known bits from a shift operator, including those with a

Event Timeline