// CHECK: [[REF:%.*]] = alloca i32
// CHECK: store i32 1, i32* [[REF]]
// CHECK: [[REG:%[0-9]+]] = addrspacecast i32* [[REF]] to i32 addrspace(4)*
- // CHECK: call spir_func i32 @_Z3barRU3AS4Kj(i32 addrspace(4)* nonnull dereferenceable(4) [[REG]])
+ // CHECK: call spir_func i32 @_Z3barRU3AS4Kj(i32 addrspace(4)* dereferenceable(4) [[REG]])
bar(1);
}
/// 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'.
static_cast<const Value *>(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<Value *>(static_cast<const Value *>(this)
+ ->stripPointerCastsSameRepresentation());
+ }
+
/// Strip off pointer casts, all-zero GEPs, aliases and invariant group
/// info.
///
// 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)
enum PointerStripKind {
PSK_ZeroIndices,
PSK_ZeroIndicesAndAliases,
+ PSK_ZeroIndicesAndAliasesSameRepresentation,
PSK_ZeroIndicesAndAliasesAndInvariantGroups,
PSK_InBoundsConstantIndices,
PSK_InBounds
if (auto *GEP = dyn_cast<GEPOperator>(V)) {
switch (StripKind) {
case PSK_ZeroIndicesAndAliases:
+ case PSK_ZeroIndicesAndAliasesSameRepresentation:
case PSK_ZeroIndicesAndAliasesAndInvariantGroups:
case PSK_ZeroIndices:
if (!GEP->hasAllZeroIndices())
break;
}
V = GEP->getPointerOperand();
- } else if (Operator::getOpcode(V) == Instruction::BitCast ||
+ } else if (Operator::getOpcode(V) == Instruction::BitCast) {
+ V = cast<Operator>(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<Operator>(V)->getOperand(0);
} else if (auto *GA = dyn_cast<GlobalAlias>(V)) {
if (StripKind == PSK_ZeroIndices || GA->isInterposable())
return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndAliases>(this);
}
+const Value *Value::stripPointerCastsSameRepresentation() const {
+ return stripPointerCastsAndOffsets<
+ PSK_ZeroIndicesAndAliasesSameRepresentation>(this);
+}
+
const Value *Value::stripPointerCastsNoFollowAliases() const {
return stripPointerCastsAndOffsets<PSK_ZeroIndices>(this);
}