diff --git a/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp --- a/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp +++ b/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp @@ -142,7 +142,8 @@ Use *CheckUse = nullptr; static bool parseRangeCheckICmp(Loop *L, ICmpInst *ICI, ScalarEvolution &SE, - const SCEV *&Index, const SCEV *&End); + const SCEVAddRecExpr *&Index, + const SCEV *&End); static void extractRangeChecksFromCond(Loop *L, ScalarEvolution &SE, Use &ConditionUse, @@ -254,7 +255,7 @@ /// is being range checked. bool InductiveRangeCheck::parseRangeCheckICmp(Loop *L, ICmpInst *ICI, ScalarEvolution &SE, - const SCEV *&Index, + const SCEVAddRecExpr *&Index, const SCEV *&End) { auto IsLoopInvariant = [&SE, L](Value *V) { return SE.isLoopInvariant(SE.getSCEV(V), L); @@ -277,6 +278,10 @@ // Both LHS and RHS are loop variant return false; + const auto *AddRec = dyn_cast(SE.getSCEV(LHS)); + if (!AddRec) + return false; + // We strengthen "0 <= I" to "0 <= I < INT_SMAX" and "I < L" to "0 <= I < L". // We can potentially do much better here. // If we want to adjust upper bound for the unsigned range check as we do it @@ -287,7 +292,7 @@ case ICmpInst::ICMP_SGE: if (match(RHS, m_ConstantInt<0>())) { - Index = SE.getSCEV(LHS); + Index = AddRec; End = SIntMaxSCEV(Index->getType()); return true; } @@ -295,7 +300,7 @@ case ICmpInst::ICMP_SGT: if (match(RHS, m_ConstantInt<-1>())) { - Index = SE.getSCEV(LHS); + Index = AddRec; End = SIntMaxSCEV(Index->getType()); return true; } @@ -303,7 +308,7 @@ case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_ULT: - Index = SE.getSCEV(LHS); + Index = AddRec; End = SE.getSCEV(RHS); return true; @@ -313,7 +318,7 @@ const SCEV *RHSS = SE.getSCEV(RHS); bool Signed = Pred == ICmpInst::ICMP_SLE; if (SE.willNotOverflow(Instruction::BinaryOps::Add, Signed, RHSS, One)) { - Index = SE.getSCEV(LHS); + Index = AddRec; End = SE.getAddExpr(RHSS, One); return true; } @@ -344,18 +349,15 @@ if (!ICI) return; - const SCEV *End = nullptr, *Index = nullptr; - if (!parseRangeCheckICmp(L, ICI, SE, Index, End)) + const SCEV *End = nullptr; + const SCEVAddRecExpr *IndexAddRec = nullptr; + if (!parseRangeCheckICmp(L, ICI, SE, IndexAddRec, End)) return; - assert(Index && "Index was not computed"); + assert(IndexAddRec && "IndexAddRec was not computed"); assert(End && "End was not computed"); - const auto *IndexAddRec = dyn_cast(Index); - bool IsAffineIndex = - IndexAddRec && (IndexAddRec->getLoop() == L) && IndexAddRec->isAffine(); - - if (!IsAffineIndex) + if ((IndexAddRec->getLoop() != L) || !IndexAddRec->isAffine()) return; InductiveRangeCheck IRC;