diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -3689,7 +3689,6 @@ } return false; } - /// Return an existing SCEV if it exists, otherwise analyze the expression and /// create a new one. const SCEV *ScalarEvolution::getSCEV(Value *V) { @@ -3717,7 +3716,10 @@ // If V is GetElementPtrInst, don't save Stripped -> {V, offset} // because it may generate add/sub instead of GEP in SCEV expansion. if (Offset != nullptr && !isa(Stripped) && - !isa(V)) + !isa(V) && + (!isa(V) || + SimplifyInstruction(cast(V), + {getDataLayout(), &TLI, &DT, &AC}) == V)) ExprValueMap[Stripped].insert({V, Offset}); } } @@ -5115,13 +5117,8 @@ if (const SCEV *S = createNodeFromSelectLikePHI(PN)) return S; - // If the PHI has a single incoming value, follow that value, unless the - // PHI's incoming blocks are in a different loop, in which case doing so - // risks breaking LCSSA form. Instcombine would normally zap these, but - // it doesn't have DominatorTree information, so it may miss cases. if (Value *V = SimplifyInstruction(PN, {getDataLayout(), &TLI, &DT, &AC})) - if (LI.replacementPreservesLCSSAForm(PN, V)) - return getSCEV(V); + return getSCEV(V); // If it's not a loop phi, we can't handle it yet. return getUnknown(PN); @@ -6561,7 +6558,9 @@ // count information isn't going to change anything. In the later // case, createNodeForPHI will perform the necessary updates on its // own when it gets to that point. - if (!isa(I) || !isa(Old)) { + if ((!isa(I) || + cast(I)->getNumIncomingValues() == 1) || + !isa(Old)) { eraseValueFromMap(It->first); forgetMemoizedResults(Old); } diff --git a/llvm/test/Analysis/ScalarEvolution/solve-quadratic-i1.ll b/llvm/test/Analysis/ScalarEvolution/solve-quadratic-i1.ll --- a/llvm/test/Analysis/ScalarEvolution/solve-quadratic-i1.ll +++ b/llvm/test/Analysis/ScalarEvolution/solve-quadratic-i1.ll @@ -57,9 +57,9 @@ ; CHECK-NEXT: %v6 = add nuw nsw i32 %v1, 1 ; CHECK-NEXT: --> {4,+,1}<%b1> U: [4,7) S: [4,7) Exits: 6 LoopDispositions: { %b1: Computable } ; CHECK-NEXT: %v7 = phi i32 [ %v1, %b1 ] -; CHECK-NEXT: --> %v7 U: [3,6) S: [3,6) +; CHECK-NEXT: --> {3,+,1}<%b1> U: [3,6) S: [3,6) --> 5 U: [5,6) S: [5,6) ; CHECK-NEXT: %v8 = phi i16 [ %v3, %b1 ] -; CHECK-NEXT: --> %v8 U: full-set S: full-set +; CHECK-NEXT: --> {3,+,4,+,1}<%b1> U: full-set S: full-set --> 12 U: [12,13) S: [12,13) ; CHECK-NEXT: Determining loop execution counts for: @f1 ; CHECK-NEXT: Loop %b3: Unpredictable backedge-taken count. ; CHECK-NEXT: Loop %b3: Unpredictable max backedge-taken count. diff --git a/llvm/test/Analysis/ScalarEvolution/solve-quadratic-overflow.ll b/llvm/test/Analysis/ScalarEvolution/solve-quadratic-overflow.ll --- a/llvm/test/Analysis/ScalarEvolution/solve-quadratic-overflow.ll +++ b/llvm/test/Analysis/ScalarEvolution/solve-quadratic-overflow.ll @@ -12,11 +12,11 @@ ; CHECK-NEXT: %v3 = mul i16 %v2, %v2 ; CHECK-NEXT: --> {1,+,3,+,2}<%b1> U: full-set S: full-set Exits: 0 LoopDispositions: { %b1: Computable } ; CHECK-NEXT: %v5 = phi i16 [ %v2, %b1 ] -; CHECK-NEXT: --> %v5 U: [-256,0) S: [-256,0) +; CHECK-NEXT: --> {-1,+,-1}<%b1> U: [-256,0) S: [-256,0) --> -256 U: [-256,-255) S: [-256,-255) ; CHECK-NEXT: %v6 = phi i16 [ %v3, %b1 ] -; CHECK-NEXT: --> %v6 U: full-set S: full-set +; CHECK-NEXT: --> {1,+,3,+,2}<%b1> U: full-set S: full-set --> 0 U: [0,1) S: [0,1) ; CHECK-NEXT: %v7 = sext i16 %v5 to i32 -; CHECK-NEXT: --> (sext i16 %v5 to i32) U: [-256,0) S: [-256,0) +; CHECK-NEXT: --> {-1,+,-1}<%b1> U: [-256,0) S: [-256,0) --> -256 U: [-256,-255) S: [-256,-255) ; CHECK-NEXT: Determining loop execution counts for: @f0 ; CHECK-NEXT: Loop %b1: backedge-taken count is 255 ; CHECK-NEXT: Loop %b1: max backedge-taken count is 255