diff options
author | Johannes Doerfert <jdoerfert@anl.gov> | 2019-01-26 23:40:35 +0000 |
---|---|---|
committer | Johannes Doerfert <jdoerfert@anl.gov> | 2019-01-26 23:40:35 +0000 |
commit | 00102c7d9579745851320bd4373db1ce2612b2c4 (patch) | |
tree | 5fcf5539fb0fba2fb16a6bf5f1b5402048f21d97 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 204bf2bbb265b5158783bacf9a67b0bc4cc57747 (diff) | |
download | llvm-00102c7d9579745851320bd4373db1ce2612b2c4.zip llvm-00102c7d9579745851320bd4373db1ce2612b2c4.tar.gz llvm-00102c7d9579745851320bd4373db1ce2612b2c4.tar.bz2 |
[ValueTracking] Look through casts when determining non-nullness
Bitcast and certain Ptr2Int/Int2Ptr instructions will not alter the
value of their operand and can therefore be looked through when we
determine non-nullness.
Differential Revision: https://reviews.llvm.org/D54956
llvm-svn: 352293
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 0aaabec..06b0bd7 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2036,11 +2036,33 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) { if (isKnownNonNullFromDominatingCondition(V, Q.CxtI, Q.DT)) return true; + // Look through bitcast operations, GEPs, and int2ptr instructions as they + // do not alter the value, or at least not the nullness property of the + // value, e.g., int2ptr is allowed to zero/sign extend the value. + // + // Note that we have to take special care to avoid looking through + // truncating casts, e.g., int2ptr/ptr2int with appropriate sizes, as well + // as casts that can alter the value, e.g., AddrSpaceCasts. if (const GEPOperator *GEP = dyn_cast<GEPOperator>(V)) if (isGEPKnownNonNull(GEP, Depth, Q)) return true; + + if (auto *BCO = dyn_cast<BitCastOperator>(V)) + return isKnownNonZero(BCO->getOperand(0), Depth, Q); + + if (auto *I2P = dyn_cast<IntToPtrInst>(V)) + if (Q.DL.getTypeSizeInBits(I2P->getSrcTy()) <= + Q.DL.getTypeSizeInBits(I2P->getDestTy())) + return isKnownNonZero(I2P->getOperand(0), Depth, Q); } + // Similar to int2ptr above, we can look through ptr2int here if the cast + // is a no-op or an extend and not a truncate. + if (auto *P2I = dyn_cast<PtrToIntInst>(V)) + if (Q.DL.getTypeSizeInBits(P2I->getSrcTy()) <= + Q.DL.getTypeSizeInBits(P2I->getDestTy())) + return isKnownNonZero(P2I->getOperand(0), Depth, Q); + unsigned BitWidth = getBitWidth(V->getType()->getScalarType(), Q.DL); // X | Y != 0 if X != 0 or Y != 0. |