Index: llvm/lib/Transforms/Utils/SimplifyIndVar.cpp =================================================================== --- llvm/lib/Transforms/Utils/SimplifyIndVar.cpp +++ llvm/lib/Transforms/Utils/SimplifyIndVar.cpp @@ -261,13 +261,16 @@ const SCEV *S = SE->getSCEVAtScope(ICmp->getOperand(IVOperIdx), ICmpLoop); const SCEV *X = SE->getSCEVAtScope(ICmp->getOperand(1 - IVOperIdx), ICmpLoop); - // If the condition is always true or always false, replace it with - // a constant value. - if (SE->isKnownPredicate(Pred, S, X)) { + // If the condition is always true or always false, in the given context, + // replace it witha constant value. + // TODO: We can sharpen the context to common dominator of all ICmp's users. + const Instruction *Context = ICmp; + if (SE->isKnownPredicateAt(Pred, S, X, Context)) { ICmp->replaceAllUsesWith(ConstantInt::getTrue(ICmp->getContext())); DeadInsts.emplace_back(ICmp); LLVM_DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n'); - } else if (SE->isKnownPredicate(ICmpInst::getInversePredicate(Pred), S, X)) { + } else if (SE->isKnownPredicateAt(ICmpInst::getInversePredicate(Pred), S, X, + Context)) { ICmp->replaceAllUsesWith(ConstantInt::getFalse(ICmp->getContext())); DeadInsts.emplace_back(ICmp); LLVM_DEBUG(dbgs() << "INDVARS: Eliminated comparison: " << *ICmp << '\n'); Index: llvm/test/Transforms/IndVarSimplify/checks_against_min_value.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/checks_against_min_value.ll +++ llvm/test/Transforms/IndVarSimplify/checks_against_min_value.ll @@ -15,8 +15,7 @@ ; CHECK-NEXT: [[CHECK:%.*]] = icmp slt i32 [[IV_NEXT]], [[IV]] ; CHECK-NEXT: br i1 [[CHECK]], label [[GUARDED]], label [[FAIL:%.*]] ; CHECK: guarded: -; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], -2147483648 -; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] +; CHECK-NEXT: br i1 true, label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; CHECK: exit.loopexit: ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: @@ -58,8 +57,7 @@ ; CHECK-NEXT: [[CHECK:%.*]] = icmp ult i32 [[IV_NEXT]], [[IV]] ; CHECK-NEXT: br i1 [[CHECK]], label [[GUARDED]], label [[FAIL:%.*]] ; CHECK: guarded: -; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ne i32 [[IV]], 0 -; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] +; CHECK-NEXT: br i1 true, label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]] ; CHECK: exit.loopexit: ; CHECK-NEXT: br label [[EXIT]] ; CHECK: exit: Index: llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll +++ llvm/test/Transforms/IndVarSimplify/eliminate-comparison.ll @@ -380,7 +380,7 @@ define void @func_13(i32* %len.ptr) { ; CHECK-LABEL: @func_13( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[LEN:%.*]] = load i32, i32* [[LEN_PTR:%.*]], align 4, [[RNG0:!range !.*]] +; CHECK-NEXT: [[LEN:%.*]] = load i32, i32* [[LEN_PTR:%.*]], align 4, !range [[RNG0:![0-9]+]] ; CHECK-NEXT: [[LEN_IS_ZERO:%.*]] = icmp eq i32 [[LEN]], 0 ; CHECK-NEXT: br i1 [[LEN_IS_ZERO]], label [[LEAVE:%.*]], label [[LOOP_PREHEADER:%.*]] ; CHECK: loop.preheader: @@ -424,7 +424,7 @@ define void @func_14(i32* %len.ptr) { ; CHECK-LABEL: @func_14( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[LEN:%.*]] = load i32, i32* [[LEN_PTR:%.*]], align 4, [[RNG0]] +; CHECK-NEXT: [[LEN:%.*]] = load i32, i32* [[LEN_PTR:%.*]], align 4, !range [[RNG0]] ; CHECK-NEXT: [[LEN_IS_ZERO:%.*]] = icmp eq i32 [[LEN]], 0 ; CHECK-NEXT: [[LEN_IS_INT_MIN:%.*]] = icmp eq i32 [[LEN]], -2147483648 ; CHECK-NEXT: [[NO_ENTRY:%.*]] = or i1 [[LEN_IS_ZERO]], [[LEN_IS_INT_MIN]] @@ -472,7 +472,7 @@ define void @func_15(i32* %len.ptr) { ; CHECK-LABEL: @func_15( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[LEN:%.*]] = load i32, i32* [[LEN_PTR:%.*]], align 4, [[RNG0]] +; CHECK-NEXT: [[LEN:%.*]] = load i32, i32* [[LEN_PTR:%.*]], align 4, !range [[RNG0]] ; CHECK-NEXT: [[LEN_ADD_1:%.*]] = add i32 [[LEN]], 1 ; CHECK-NEXT: [[LEN_ADD_1_IS_ZERO:%.*]] = icmp eq i32 [[LEN_ADD_1]], 0 ; CHECK-NEXT: br i1 [[LEN_ADD_1_IS_ZERO]], label [[LEAVE:%.*]], label [[LOOP_PREHEADER:%.*]] @@ -517,7 +517,7 @@ define void @func_16(i32* %len.ptr) { ; CHECK-LABEL: @func_16( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[LEN:%.*]] = load i32, i32* [[LEN_PTR:%.*]], align 4, [[RNG0]] +; CHECK-NEXT: [[LEN:%.*]] = load i32, i32* [[LEN_PTR:%.*]], align 4, !range [[RNG0]] ; CHECK-NEXT: [[LEN_ADD_5:%.*]] = add i32 [[LEN]], 5 ; CHECK-NEXT: [[ENTRY_COND_0:%.*]] = icmp slt i32 [[LEN]], 2147483643 ; CHECK-NEXT: [[ENTRY_COND_1:%.*]] = icmp slt i32 4, [[LEN_ADD_5]] @@ -624,7 +624,7 @@ define i1 @func_18(i16* %tmp20, i32* %len.addr) { ; CHECK-LABEL: @func_18( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[LEN:%.*]] = load i32, i32* [[LEN_ADDR:%.*]], align 4, [[RNG0]] +; CHECK-NEXT: [[LEN:%.*]] = load i32, i32* [[LEN_ADDR:%.*]], align 4, !range [[RNG0]] ; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i32 [[LEN]], 0 ; CHECK-NEXT: br i1 [[TMP18]], label [[BB2:%.*]], label [[BB0_PREHEADER:%.*]] ; CHECK: bb0.preheader: @@ -686,7 +686,7 @@ define void @func_19(i32* %length.ptr) { ; CHECK-LABEL: @func_19( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, [[RNG0]] +; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, !range [[RNG0]] ; CHECK-NEXT: [[LENGTH_IS_NONZERO:%.*]] = icmp ne i32 [[LENGTH]], 0 ; CHECK-NEXT: br i1 [[LENGTH_IS_NONZERO]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]] ; CHECK: loop.preheader: @@ -774,7 +774,7 @@ define void @func_21(i32* %length.ptr) { ; CHECK-LABEL: @func_21( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, [[RNG0]] +; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, !range [[RNG0]] ; CHECK-NEXT: [[LIM:%.*]] = sub i32 [[LENGTH]], 1 ; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp sgt i32 [[LENGTH]], 1 ; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]] @@ -819,7 +819,7 @@ define void @func_22(i32* %length.ptr) { ; CHECK-LABEL: @func_22( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, [[RNG0]] +; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, !range [[RNG0]] ; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp sgt i32 [[LENGTH]], 1 ; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]] ; CHECK: loop.preheader: @@ -861,7 +861,7 @@ define void @func_23(i32* %length.ptr) { ; CHECK-LABEL: @func_23( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, [[RNG0]] +; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_PTR:%.*]], align 4, !range [[RNG0]] ; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp ult i32 4, [[LENGTH]] ; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]] ; CHECK: loop.preheader: @@ -902,7 +902,7 @@ define void @func_24(i32* %init.ptr) { ; CHECK-LABEL: @func_24( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[INIT:%.*]] = load i32, i32* [[INIT_PTR:%.*]], align 4, [[RNG0]] +; CHECK-NEXT: [[INIT:%.*]] = load i32, i32* [[INIT_PTR:%.*]], align 4, !range [[RNG0]] ; CHECK-NEXT: [[ENTRY_COND:%.*]] = icmp ugt i32 [[INIT]], 4 ; CHECK-NEXT: br i1 [[ENTRY_COND]], label [[LOOP_PREHEADER:%.*]], label [[LEAVE:%.*]] ; CHECK: loop.preheader: @@ -951,11 +951,9 @@ ; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[IV]], 0 ; CHECK-NEXT: br i1 [[C1]], label [[CHECKED_1:%.*]], label [[FAIL:%.*]] ; CHECK: checked.1: -; CHECK-NEXT: [[C2:%.*]] = icmp ne i32 [[IV]], 0 -; CHECK-NEXT: br i1 [[C2]], label [[CHECKED_2:%.*]], label [[FAIL]] +; CHECK-NEXT: br i1 true, label [[CHECKED_2:%.*]], label [[FAIL]] ; CHECK: checked.2: -; CHECK-NEXT: [[C3:%.*]] = icmp ne i32 [[IV]], 0 -; CHECK-NEXT: br i1 [[C3]], label [[BACKEDGE]], label [[FAIL]] +; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[FAIL]] ; CHECK: backedge: ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 758394 ; CHECK-NEXT: [[LOOP_COND:%.*]] = call i1 @cond_func() @@ -1003,11 +1001,9 @@ ; CHECK-NEXT: [[C1:%.*]] = icmp slt i32 [[IV]], 0 ; CHECK-NEXT: br i1 [[C1]], label [[CHECKED_1:%.*]], label [[FAIL:%.*]] ; CHECK: checked.1: -; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[IV]], 1 -; CHECK-NEXT: br i1 [[C2]], label [[CHECKED_2:%.*]], label [[FAIL]] +; CHECK-NEXT: br i1 true, label [[CHECKED_2:%.*]], label [[FAIL]] ; CHECK: checked.2: -; CHECK-NEXT: [[C3:%.*]] = icmp slt i32 [[IV]], 2 -; CHECK-NEXT: br i1 [[C3]], label [[BACKEDGE]], label [[FAIL]] +; CHECK-NEXT: br i1 true, label [[BACKEDGE]], label [[FAIL]] ; CHECK: backedge: ; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 758394 ; CHECK-NEXT: [[LOOP_COND:%.*]] = call i1 @cond_func() Index: llvm/test/Transforms/IndVarSimplify/scev-expander-preserve-lcssa.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/scev-expander-preserve-lcssa.ll +++ llvm/test/Transforms/IndVarSimplify/scev-expander-preserve-lcssa.ll @@ -116,7 +116,7 @@ ; CHECK-NEXT: [[C_2:%.*]] = call i1 @cond() ; CHECK-NEXT: br i1 [[C_2]], label [[IF_END106:%.*]], label [[RETURN_LOOPEXIT:%.*]] ; CHECK: if.end106: -; CHECK-NEXT: br i1 false, label [[FOR_BODY84]], label [[RETURN_LOOPEXIT]] +; CHECK-NEXT: br i1 true, label [[FOR_BODY84]], label [[RETURN_LOOPEXIT]] ; CHECK: return.loopexit: ; CHECK-NEXT: br label [[RETURN]] ; CHECK: return.loopexit1: