diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-05-01 15:19:41 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-05-16 14:17:11 +0200 |
commit | d86fff6ae7cfd6666511e9c2129711b88ed514be (patch) | |
tree | 285f8adc828cd6f7e0f9098082b90e3058c7ff13 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 3f66bb20174eb6d1f7689eeb5fbd19128d504063 (diff) | |
download | llvm-d86fff6ae7cfd6666511e9c2129711b88ed514be.zip llvm-d86fff6ae7cfd6666511e9c2129711b88ed514be.tar.gz llvm-d86fff6ae7cfd6666511e9c2129711b88ed514be.tar.bz2 |
[ValueTracking] Fix computeKnownBits() with bitwidth-changing ptrtoint
computeKnownBitsFromAssume() currently asserts if m_V matches a
ptrtoint that changes the bitwidth. Because InstCombine
canonicalizes ptrtoint instructions to use explicit zext/trunc,
we never ran into the issue in practice. I'm adding unit tests,
as I don't know if this can be triggered via IR anywhere.
Fix this by calling anyextOrTrunc(BitWidth) on the computed
KnownBits. Note that we are going from the KnownBits of the
ptrtoint result to the KnownBits of the ptrtoint operand,
so we need to truncate if the ptrtoint zexted and anyext if
the ptrtoint truncated.
Differential Revision: https://reviews.llvm.org/D79234
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 94 |
1 files changed, 48 insertions, 46 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index a4b0202..8d69df3 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -785,6 +785,7 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, if (!Cmp) continue; + // Note that ptrtoint may change the bitwidth. Value *A, *B; auto m_V = m_CombineOr(m_Specific(V), m_PtrToInt(m_Specific(V))); @@ -797,18 +798,18 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, // assume(v = a) if (match(Cmp, m_c_ICmp(Pred, m_V, m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); Known.Zero |= RHSKnown.Zero; Known.One |= RHSKnown.One; // assume(v & b = a) } else if (match(Cmp, m_c_ICmp(Pred, m_c_And(m_V, m_Value(B)), m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); - KnownBits MaskKnown(BitWidth); - computeKnownBits(B, MaskKnown, Depth+1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); + KnownBits MaskKnown = + computeKnownBits(B, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); // For those bits in the mask that are known to be one, we can propagate // known bits from the RHS to V. @@ -818,10 +819,10 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, } else if (match(Cmp, m_c_ICmp(Pred, m_Not(m_c_And(m_V, m_Value(B))), m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); - KnownBits MaskKnown(BitWidth); - computeKnownBits(B, MaskKnown, Depth+1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); + KnownBits MaskKnown = + computeKnownBits(B, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); // For those bits in the mask that are known to be one, we can propagate // inverted known bits from the RHS to V. @@ -831,10 +832,10 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, } else if (match(Cmp, m_c_ICmp(Pred, m_c_Or(m_V, m_Value(B)), m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); - KnownBits BKnown(BitWidth); - computeKnownBits(B, BKnown, Depth+1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); + KnownBits BKnown = + computeKnownBits(B, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); // For those bits in B that are known to be zero, we can propagate known // bits from the RHS to V. @@ -844,10 +845,10 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, } else if (match(Cmp, m_c_ICmp(Pred, m_Not(m_c_Or(m_V, m_Value(B))), m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); - KnownBits BKnown(BitWidth); - computeKnownBits(B, BKnown, Depth+1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); + KnownBits BKnown = + computeKnownBits(B, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); // For those bits in B that are known to be zero, we can propagate // inverted known bits from the RHS to V. @@ -857,10 +858,10 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, } else if (match(Cmp, m_c_ICmp(Pred, m_c_Xor(m_V, m_Value(B)), m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); - KnownBits BKnown(BitWidth); - computeKnownBits(B, BKnown, Depth+1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); + KnownBits BKnown = + computeKnownBits(B, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); // For those bits in B that are known to be zero, we can propagate known // bits from the RHS to V. For those bits in B that are known to be one, @@ -873,10 +874,10 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, } else if (match(Cmp, m_c_ICmp(Pred, m_Not(m_c_Xor(m_V, m_Value(B))), m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); - KnownBits BKnown(BitWidth); - computeKnownBits(B, BKnown, Depth+1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); + KnownBits BKnown = + computeKnownBits(B, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); // For those bits in B that are known to be zero, we can propagate // inverted known bits from the RHS to V. For those bits in B that are @@ -889,8 +890,9 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, } else if (match(Cmp, m_c_ICmp(Pred, m_Shl(m_V, m_ConstantInt(C)), m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT) && C < BitWidth) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); + // For those bits in RHS that are known, we can propagate them to known // bits in V shifted to the right by C. RHSKnown.Zero.lshrInPlace(C); @@ -901,8 +903,8 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, } else if (match(Cmp, m_c_ICmp(Pred, m_Not(m_Shl(m_V, m_ConstantInt(C))), m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT) && C < BitWidth) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); // For those bits in RHS that are known, we can propagate them inverted // to known bits in V shifted to the right by C. RHSKnown.One.lshrInPlace(C); @@ -913,8 +915,8 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, } else if (match(Cmp, m_c_ICmp(Pred, m_Shr(m_V, m_ConstantInt(C)), m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT) && C < BitWidth) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); // For those bits in RHS that are known, we can propagate them to known // bits in V shifted to the right by C. Known.Zero |= RHSKnown.Zero << C; @@ -923,8 +925,8 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, } else if (match(Cmp, m_c_ICmp(Pred, m_Not(m_Shr(m_V, m_ConstantInt(C))), m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT) && C < BitWidth) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); // For those bits in RHS that are known, we can propagate them inverted // to known bits in V shifted to the right by C. Known.Zero |= RHSKnown.One << C; @@ -935,8 +937,8 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, // assume(v >=_s c) where c is non-negative if (match(Cmp, m_ICmp(Pred, m_V, m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth + 1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth + 1, Query(Q, I)).anyextOrTrunc(BitWidth); if (RHSKnown.isNonNegative()) { // We know that the sign bit is zero. @@ -948,8 +950,8 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, // assume(v >_s c) where c is at least -1. if (match(Cmp, m_ICmp(Pred, m_V, m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth + 1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth + 1, Query(Q, I)).anyextOrTrunc(BitWidth); if (RHSKnown.isAllOnes() || RHSKnown.isNonNegative()) { // We know that the sign bit is zero. @@ -961,8 +963,8 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, // assume(v <=_s c) where c is negative if (match(Cmp, m_ICmp(Pred, m_V, m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth + 1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth + 1, Query(Q, I)).anyextOrTrunc(BitWidth); if (RHSKnown.isNegative()) { // We know that the sign bit is one. @@ -974,8 +976,8 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, // assume(v <_s c) where c is non-positive if (match(Cmp, m_ICmp(Pred, m_V, m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); if (RHSKnown.isZero() || RHSKnown.isNegative()) { // We know that the sign bit is one. @@ -987,8 +989,8 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, // assume(v <=_u c) if (match(Cmp, m_ICmp(Pred, m_V, m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); // Whatever high bits in c are zero are known to be zero. Known.Zero.setHighBits(RHSKnown.countMinLeadingZeros()); @@ -998,8 +1000,8 @@ static void computeKnownBitsFromAssume(const Value *V, KnownBits &Known, // assume(v <_u c) if (match(Cmp, m_ICmp(Pred, m_V, m_Value(A))) && isValidAssumeForContext(I, Q.CxtI, Q.DT)) { - KnownBits RHSKnown(BitWidth); - computeKnownBits(A, RHSKnown, Depth+1, Query(Q, I)); + KnownBits RHSKnown = + computeKnownBits(A, Depth+1, Query(Q, I)).anyextOrTrunc(BitWidth); // If the RHS is known zero, then this assumption must be wrong (nothing // is unsigned less than zero). Signal a conflict and get out of here. |