Index: lib/IR/Value.cpp =================================================================== --- lib/IR/Value.cpp +++ lib/IR/Value.cpp @@ -421,43 +421,59 @@ }; template +static Value *stripOne(Value *V) { + if (GEPOperator *GEP = dyn_cast(V)) { + switch (StripKind) { + case PSK_ZeroIndicesAndAliases: + case PSK_ZeroIndices: + if (!GEP->hasAllZeroIndices()) + return nullptr; + break; + case PSK_InBoundsConstantIndices: + if (!GEP->hasAllConstantIndices()) + return nullptr; + // fallthrough + case PSK_InBounds: + if (!GEP->isInBounds()) + return nullptr; + break; + } + return GEP->getPointerOperand(); + } else if (Operator::getOpcode(V) == Instruction::BitCast || + Operator::getOpcode(V) == Instruction::AddrSpaceCast) { + return cast(V)->getOperand(0); + } else if (GlobalAlias *GA = dyn_cast(V)) { + if (StripKind == PSK_ZeroIndices || GA->mayBeOverridden()) + return nullptr; + return GA->getAliasee(); + } else { + return nullptr; + } +} + +template static Value *stripPointerCastsAndOffsets(Value *V) { if (!V->getType()->isPointerTy()) return V; + // This function is performance sensitive so try the common case first + // before constructing the SmallPtrSet. + Value *Next = stripOne(V); + if (Next == nullptr) + return V; + // Even though we don't look through PHI nodes, we could be called on an // instruction in an unreachable block, which may be on a cycle. SmallPtrSet Visited; - Visited.insert(V); + if (!Visited.insert(Next).second) + return Next; + V = Next; do { - if (GEPOperator *GEP = dyn_cast(V)) { - switch (StripKind) { - case PSK_ZeroIndicesAndAliases: - case PSK_ZeroIndices: - if (!GEP->hasAllZeroIndices()) - return V; - break; - case PSK_InBoundsConstantIndices: - if (!GEP->hasAllConstantIndices()) - return V; - // fallthrough - case PSK_InBounds: - if (!GEP->isInBounds()) - return V; - break; - } - V = GEP->getPointerOperand(); - } else if (Operator::getOpcode(V) == Instruction::BitCast || - Operator::getOpcode(V) == Instruction::AddrSpaceCast) { - V = cast(V)->getOperand(0); - } else if (GlobalAlias *GA = dyn_cast(V)) { - if (StripKind == PSK_ZeroIndices || GA->mayBeOverridden()) - return V; - V = GA->getAliasee(); - } else { + Next = stripOne(V); + if (Next == nullptr) return V; - } + V = Next; assert(V->getType()->isPointerTy() && "Unexpected operand type!"); } while (Visited.insert(V).second);