Index: lib/Transforms/Scalar/IndVarSimplify.cpp =================================================================== --- lib/Transforms/Scalar/IndVarSimplify.cpp +++ lib/Transforms/Scalar/IndVarSimplify.cpp @@ -809,6 +809,20 @@ bool IsSigned = Cast->getOpcode() == Instruction::SExt; if (!IsSigned && Cast->getOpcode() != Instruction::ZExt) return; + + // If this is a zext, mark this IV as signed if it is known to be + // non-negative and the zext has a GEP user. + if (!IsSigned) { + const SCEV *NarrowIVSCEV = SE->getSCEV(WI.NarrowIV); + bool NeverNegative = + SE->isKnownPredicate(ICmpInst::ICMP_SGE, NarrowIVSCEV, + SE->getConstant(NarrowIVSCEV->getType(), 0)); + if (NeverNegative && any_of(Cast->users(), [](User *U) { + auto* CastUser = cast(U); + return CastUser->getOpcode() == Instruction::GetElementPtr; + })) + IsSigned = true; + } Type *Ty = Cast->getType(); uint64_t Width = SE->getTypeSizeInBits(Ty);