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 @@ -6582,15 +6582,11 @@ // instructions can map to the same SCEV. If we apply NSW or NUW from I to // the SCEV, we must guarantee no wrapping for that SCEV also when it is // derived from other instructions that map to the same SCEV. We cannot make - // that guarantee for cases where I is not executed. So we need to find the - // loop that I is considered in relation to and prove that I is executed for - // every iteration of that loop. That implies that the value that I - // calculates does not wrap anywhere in the loop, so then we can apply the - // flags to the SCEV. - // - // We check isLoopInvariant to disambiguate in case we are adding recurrences - // from different loops, so that we know which loop to prove that I is - // executed in. + // that guarantee for cases where I is not executed. So we need to find a + // upper bound on the defining scope for the SCEV, and prove that I is + // executed every time we enter that scope. When the bounding scope is a + // loop (the common case), this is equivalent to proving I executes on every + // iteration of that loop. for (const Use &Op : I->operands()) { // I could be an extractvalue from a call to an overflow intrinsic. // TODO: We can do better here in some cases. @@ -6598,15 +6594,7 @@ return false; const SCEV *OpS = getSCEV(Op); if (auto *AddRecS = dyn_cast(OpS)) { - const bool AllOtherOpsLoopInvariant = - llvm::all_of(I->operands(), [&](const Use &Op2) -> bool { - if (Op.getOperandNo() == Op2.getOperandNo()) - return true; - const SCEV *OtherOp = getSCEV(Op2); - return isLoopInvariant(OtherOp, AddRecS->getLoop()); - }); - if (AllOtherOpsLoopInvariant && - isGuaranteedToExecuteForEveryIteration(I, AddRecS->getLoop())) + if (isGuaranteedToExecuteForEveryIteration(I, AddRecS->getLoop())) return true; } } diff --git a/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll b/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll --- a/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll +++ b/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll @@ -142,9 +142,9 @@ ; CHECK-NEXT: %i.next = add nuw i32 %i, 1 ; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: <> LoopDispositions: { %loop: Computable } ; CHECK-NEXT: %of_interest = add nuw nsw i32 %i.next, %offset -; CHECK-NEXT: --> ({1,+,1}<%loop> + %offset) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> ({1,+,1}<%loop> + %offset) U: [1,0) S: [1,0) Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: %gep2 = getelementptr i32, i32* %input, i32 %of_interest -; CHECK-NEXT: --> ((4 * (sext i32 ({1,+,1}<%loop> + %offset) to i64)) + %input) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: --> ((4 * ((sext i32 {1,+,1}<%loop> to i64) + (sext i32 %offset to i64))) + %input) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } ; CHECK-NEXT: Determining loop execution counts for: @test-add-scope-bound ; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. ; CHECK-NEXT: Loop %loop: Unpredictable max backedge-taken count.