diff --git a/llvm/include/llvm/IR/Value.h b/llvm/include/llvm/IR/Value.h --- a/llvm/include/llvm/IR/Value.h +++ b/llvm/include/llvm/IR/Value.h @@ -493,7 +493,7 @@ /// swifterror attribute. bool isSwiftError() const; - /// Strip off pointer casts, all-zero GEPs, and aliases. + /// Strip off pointer casts, all-zero GEPs, address space casts, and aliases. /// /// Returns the original uncasted value. If this is called on a non-pointer /// value, it returns 'this'. @@ -503,6 +503,18 @@ static_cast(this)->stripPointerCasts()); } + /// Strip off pointer casts, all-zero GEPs, address space casts, and aliases + /// but ensures the bit pattern of the result is equal to the bit pattern of + /// the underlying value. + /// + /// Returns the original uncasted value with the same bit pattern. If this is + /// called on a non-pointer value, it returns 'this'. + const Value *stripPointerCastsSameBitPattern() const; + Value *stripPointerCastsSameBitPattern() { + return const_cast( + static_cast(this)->stripPointerCastsSameBitPattern()); + } + /// Strip off pointer casts, all-zero GEPs, aliases and invariant group /// info. /// diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -1739,7 +1739,7 @@ // through would still be correct. const DataLayout &DL = CxtI->getModule()->getDataLayout(); if (V->getType()->isPointerTy() && C->isNullValue() && - isKnownNonZero(V->stripPointerCasts(), DL)) { + isKnownNonZero(V->stripPointerCastsSameBitPattern(), DL)) { if (Pred == ICmpInst::ICMP_EQ) return LazyValueInfo::False; else if (Pred == ICmpInst::ICMP_NE) diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -460,6 +460,7 @@ enum PointerStripKind { PSK_ZeroIndices, PSK_ZeroIndicesAndAliases, + PSK_ZeroIndicesAndAliasesSameBitPattern, PSK_ZeroIndicesAndAliasesAndInvariantGroups, PSK_InBoundsConstantIndices, PSK_InBounds @@ -479,6 +480,7 @@ if (auto *GEP = dyn_cast(V)) { switch (StripKind) { case PSK_ZeroIndicesAndAliases: + case PSK_ZeroIndicesAndAliasesSameBitPattern: case PSK_ZeroIndicesAndAliasesAndInvariantGroups: case PSK_ZeroIndices: if (!GEP->hasAllZeroIndices()) @@ -494,7 +496,9 @@ break; } V = GEP->getPointerOperand(); - } else if (Operator::getOpcode(V) == Instruction::BitCast || + } else if (Operator::getOpcode(V) == Instruction::BitCast) { + V = cast(V)->getOperand(0); + } else if (StripKind != PSK_ZeroIndicesAndAliasesSameBitPattern && Operator::getOpcode(V) == Instruction::AddrSpaceCast) { V = cast(V)->getOperand(0); } else if (auto *GA = dyn_cast(V)) { @@ -530,6 +534,11 @@ return stripPointerCastsAndOffsets(this); } +const Value *Value::stripPointerCastsSameBitPattern() const { + return stripPointerCastsAndOffsets( + this); +} + const Value *Value::stripPointerCastsNoFollowAliases() const { return stripPointerCastsAndOffsets(this); }