diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h index d0de008db26..3f8caa668e5 100644 --- a/include/llvm/IR/Value.h +++ b/include/llvm/IR/Value.h @@ -493,7 +493,7 @@ public: /// 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,17 @@ public: static_cast(this)->stripPointerCasts()); } + /// Strip off pointer casts, all-zero GEPs, address space casts, and aliases + /// but ensures the representation of the result stays the same. + /// + /// Returns the original uncasted value with the same representation. If this + /// is called on a non-pointer value, it returns 'this'. + const Value *stripPointerCastsSameRepresentation() const; + Value *stripPointerCastsSameRepresentation() { + return const_cast(static_cast(this) + ->stripPointerCastsSameRepresentation()); + } + /// Strip off pointer casts, all-zero GEPs, aliases and invariant group /// info. /// diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp index 53e9f49a571..542ff709d47 100644 --- a/lib/Analysis/LazyValueInfo.cpp +++ b/lib/Analysis/LazyValueInfo.cpp @@ -1803,7 +1803,7 @@ LazyValueInfo::getPredicateAt(unsigned Pred, Value *V, Constant *C, // through would still be correct. const DataLayout &DL = CxtI->getModule()->getDataLayout(); if (V->getType()->isPointerTy() && C->isNullValue() && - isKnownNonZero(V->stripPointerCasts(), DL)) { + isKnownNonZero(V->stripPointerCastsSameRepresentation(), DL)) { if (Pred == ICmpInst::ICMP_EQ) return LazyValueInfo::False; else if (Pred == ICmpInst::ICMP_NE) diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp index cf32a66c901..9e0a43ce1e3 100644 --- a/lib/IR/Value.cpp +++ b/lib/IR/Value.cpp @@ -460,6 +460,7 @@ namespace { enum PointerStripKind { PSK_ZeroIndices, PSK_ZeroIndicesAndAliases, + PSK_ZeroIndicesAndAliasesSameRepresentation, PSK_ZeroIndicesAndAliasesAndInvariantGroups, PSK_InBoundsConstantIndices, PSK_InBounds @@ -479,6 +480,7 @@ static const Value *stripPointerCastsAndOffsets(const Value *V) { if (auto *GEP = dyn_cast(V)) { switch (StripKind) { case PSK_ZeroIndicesAndAliases: + case PSK_ZeroIndicesAndAliasesSameRepresentation: case PSK_ZeroIndicesAndAliasesAndInvariantGroups: case PSK_ZeroIndices: if (!GEP->hasAllZeroIndices()) @@ -494,8 +496,12 @@ static const Value *stripPointerCastsAndOffsets(const Value *V) { 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_ZeroIndicesAndAliasesSameRepresentation && Operator::getOpcode(V) == Instruction::AddrSpaceCast) { + // TODO: If we know an address space cast will not change the + // representation we could look through it here as well. V = cast(V)->getOperand(0); } else if (auto *GA = dyn_cast(V)) { if (StripKind == PSK_ZeroIndices || GA->isInterposable()) @@ -530,6 +536,11 @@ const Value *Value::stripPointerCasts() const { return stripPointerCastsAndOffsets(this); } +const Value *Value::stripPointerCastsSameRepresentation() const { + return stripPointerCastsAndOffsets< + PSK_ZeroIndicesAndAliasesSameRepresentation>(this); +} + const Value *Value::stripPointerCastsNoFollowAliases() const { return stripPointerCastsAndOffsets(this); }