diff options
| -rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 25 | ||||
| -rw-r--r-- | llvm/test/Analysis/ScalarEvolution/nsw.ll | 36 |
2 files changed, 49 insertions, 12 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index d76b0f30490..111b9b61d1e 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -4880,22 +4880,23 @@ bool ScalarEvolution::isAddRecNeverPoison(const Instruction *I, const Loop *L) { return false; SmallPtrSet<const Instruction *, 16> Pushed; - SmallVector<const Instruction *, 8> Stack; + SmallVector<const Instruction *, 8> PoisonStack; + // We start by assuming \c I, the post-inc add recurrence, is poison. Only + // things that are known to be fully poison under that assumption go on the + // PoisonStack. Pushed.insert(I); - for (auto *U : I->users()) - if (Pushed.insert(cast<Instruction>(U)).second) - Stack.push_back(cast<Instruction>(U)); + PoisonStack.push_back(I); bool LatchControlDependentOnPoison = false; - while (!Stack.empty()) { - const Instruction *I = Stack.pop_back_val(); - - for (auto *U : I->users()) { - if (propagatesFullPoison(cast<Instruction>(U))) { - if (Pushed.insert(cast<Instruction>(U)).second) - Stack.push_back(cast<Instruction>(U)); - } else if (auto *BI = dyn_cast<BranchInst>(U)) { + while (!PoisonStack.empty()) { + const Instruction *Poison = PoisonStack.pop_back_val(); + + for (auto *PoisonUser : Poison->users()) { + if (propagatesFullPoison(cast<Instruction>(PoisonUser))) { + if (Pushed.insert(cast<Instruction>(PoisonUser)).second) + PoisonStack.push_back(cast<Instruction>(PoisonUser)); + } else if (auto *BI = dyn_cast<BranchInst>(PoisonUser)) { assert(BI->isConditional() && "Only possibility!"); if (BI->getParent() == LatchBB) { LatchControlDependentOnPoison = true; diff --git a/llvm/test/Analysis/ScalarEvolution/nsw.ll b/llvm/test/Analysis/ScalarEvolution/nsw.ll index d015717e354..e89973be2b0 100644 --- a/llvm/test/Analysis/ScalarEvolution/nsw.ll +++ b/llvm/test/Analysis/ScalarEvolution/nsw.ll @@ -204,3 +204,39 @@ for.body: for.end: ret void } + + +define void @bad_postinc_nsw_a(i32 %n) { +; CHECK-LABEL: Classifying expressions for: @bad_postinc_nsw_a +entry: + br label %loop + +loop: + %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ] + %iv.inc = add nsw i32 %iv, 7 +; CHECK: %iv.inc = add nsw i32 %iv, 7 +; CHECK-NEXT: --> {7,+,7}<nuw><%loop> + %becond = icmp ult i32 %iv, %n + br i1 %becond, label %loop, label %leave + +leave: + ret void +} + +define void @bad_postinc_nsw_b(i32 %n) { +; CHECK-LABEL: Classifying expressions for: @bad_postinc_nsw_b +entry: + br label %loop + +loop: + %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ] + %iv.inc = add nsw i32 %iv, 7 + %iv.inc.and = and i32 %iv.inc, 0 +; CHECK: %iv.inc = add nsw i32 %iv, 7 +; CHECK-NEXT: --> {7,+,7}<nuw><%loop> + %becond = icmp ult i32 %iv.inc.and, %n + br i1 %becond, label %loop, label %leave + +leave: + ret void +} |

