diff options
| -rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 16 | ||||
| -rw-r--r-- | llvm/test/Analysis/ScalarEvolution/zext-wrap.ll | 2 | ||||
| -rw-r--r-- | llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll | 39 | 
3 files changed, 55 insertions, 2 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index f87a5596c86..32d3d36c739 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -6994,6 +6994,22 @@ ScalarEvolution::isLoopBackedgeGuardedByCond(const Loop *L,    SaveAndRestore<bool> ClearOnExit(WalkingBEDominatingConds, true); +  // See if we can exploit a trip count to prove the predicate. +  const auto &BETakenInfo = getBackedgeTakenInfo(L); +  const SCEV *LatchBECount = BETakenInfo.getExact(Latch, this); +  if (LatchBECount != getCouldNotCompute()) { +    // We know that Latch branches back to the loop header exactly +    // LatchBECount times.  This means the backdege condition at Latch is +    // equivalent to  "{0,+,1} u< LatchBECount". +    Type *Ty = LatchBECount->getType(); +    auto NoWrapFlags = SCEV::NoWrapFlags(SCEV::FlagNUW | SCEV::FlagNW); +    const SCEV *LoopCounter = +      getAddRecExpr(getZero(Ty), getOne(Ty), L, NoWrapFlags); +    if (isImpliedCond(Pred, LHS, RHS, ICmpInst::ICMP_ULT, LoopCounter, +                      LatchBECount)) +      return true; +  } +    // Check conditions due to any @llvm.assume intrinsics.    for (auto &AssumeVH : AC.assumptions()) {      if (!AssumeVH) diff --git a/llvm/test/Analysis/ScalarEvolution/zext-wrap.ll b/llvm/test/Analysis/ScalarEvolution/zext-wrap.ll index f56e4556c69..5bc149e2309 100644 --- a/llvm/test/Analysis/ScalarEvolution/zext-wrap.ll +++ b/llvm/test/Analysis/ScalarEvolution/zext-wrap.ll @@ -10,7 +10,7 @@ bb.i:           ; preds = %bb1.i, %bb.nph  ; This cast shouldn't be folded into the addrec.  ; CHECK: %tmp = zext i8 %l_95.0.i1 to i16 -; CHECK: -->  (zext i8 {0,+,-1}<%bb.i> to i16){{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: 2 +; CHECK: -->  (zext i8 {0,+,-1}<nw><%bb.i> to i16){{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: 2          %tmp = zext i8 %l_95.0.i1 to i16 diff --git a/llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll b/llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll index 261ba387028..957ebb7cfbf 100644 --- a/llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll +++ b/llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll @@ -356,5 +356,42 @@ define void @func_17(i32* %len.ptr) {    ret void  } -!0 = !{i32 0, i32 2147483647} +define i1 @func_18(i16* %tmp20, i32* %len.addr) { +; CHECK-LABEL: @func_18( +entry: +  %len = load i32, i32* %len.addr, !range !0 +  %tmp18 = icmp eq i32 %len, 0 +  br i1 %tmp18, label %bb2, label %bb0.preheader + +bb0.preheader: +  br label %bb0 + +bb0: +; CHECK: bb0: +  %var_0.in = phi i32 [ %var_0, %bb1 ], [ %len, %bb0.preheader ] +  %var_1 = phi i32 [ %tmp30, %bb1 ], [ 0, %bb0.preheader ] +  %var_0 = add nsw i32 %var_0.in, -1 +  %tmp23 = icmp ult i32 %var_1, %len +; CHECK: br i1 true, label %stay, label %bb2.loopexit +  br i1 %tmp23, label %stay, label %bb2 + +stay: +; CHECK: stay: +  %tmp25 = getelementptr inbounds i16, i16* %tmp20, i32 %var_1 +  %tmp26 = load i16, i16* %tmp25 +  %tmp29 = icmp eq i16 %tmp26, 0 +  br i1 %tmp29, label %bb1, label %bb2 + +bb1: +  %tmp30 = add i32 %var_1, 1 +  %tmp31 = icmp eq i32 %var_0, 0 +  br i1 %tmp31, label %bb3, label %bb0 + +bb2: +  ret i1 false + +bb3: +  ret i1 true +} +!0 = !{i32 0, i32 2147483647}  | 

