Index: include/llvm/Analysis/ScalarEvolution.h =================================================================== --- include/llvm/Analysis/ScalarEvolution.h +++ include/llvm/Analysis/ScalarEvolution.h @@ -507,6 +507,13 @@ bool Inverse); /// Test whether the condition described by Pred, LHS, and RHS is true + /// whenever the condition described by FoundPred, FoundLHS, FoundRHS is + /// true. + bool isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS, + const SCEV *RHS, ICmpInst::Predicate FoundPred, + const SCEV *FoundLHS, const SCEV *FoundRHS); + + /// Test whether the condition described by Pred, LHS, and RHS is true /// whenever the condition described by Pred, FoundLHS, and FoundRHS is /// true. bool isImpliedCondOperands(ICmpInst::Predicate Pred, Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -7162,6 +7162,14 @@ const SCEV *FoundLHS = getSCEV(ICI->getOperand(0)); const SCEV *FoundRHS = getSCEV(ICI->getOperand(1)); + return isImpliedCond(Pred, LHS, RHS, FoundPred, FoundLHS, FoundRHS); +} + +bool ScalarEvolution::isImpliedCond(ICmpInst::Predicate Pred, const SCEV *LHS, + const SCEV *RHS, + ICmpInst::Predicate FoundPred, + const SCEV *FoundLHS, + const SCEV *FoundRHS) { // Balance the types. if (getTypeSizeInBits(LHS->getType()) < getTypeSizeInBits(FoundLHS->getType())) { Index: test/Transforms/IndVarSimplify/eliminate-comparison.ll =================================================================== --- test/Transforms/IndVarSimplify/eliminate-comparison.ll +++ test/Transforms/IndVarSimplify/eliminate-comparison.ll @@ -266,4 +266,31 @@ ret void } +define void @func_15(i32* %len.ptr) { +; CHECK-LABEL: @func_15( + entry: + %len = load i32, i32* %len.ptr, !range !0 + %len.add.1 = add i32 %len, 1 + %len.add.1.is.zero = icmp eq i32 %len.add.1, 0 + br i1 %len.add.1.is.zero, label %leave, label %loop + + loop: +; CHECK: loop: + %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ] + call void @side_effect() + %iv.inc = add i32 %iv, 1 + %iv.cmp = icmp ult i32 %iv, %len.add.1 + br i1 %iv.cmp, label %be, label %leave +; CHECK: br i1 true, label %be, label %leave + + be: + call void @side_effect() + %be.cond = icmp ult i32 %iv, %len + br i1 %be.cond, label %loop, label %leave + + leave: + ret void +} + !0 = !{i32 0, i32 2147483647} +