diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -7037,7 +7037,7 @@ ConstantRange RHS = computeConstantRange(Cmp->getOperand(1), UseInstrInfo, AC, I, Depth + 1); CR = CR.intersectWith( - ConstantRange::makeSatisfyingICmpRegion(Cmp->getPredicate(), RHS)); + ConstantRange::makeAllowedICmpRegion(Cmp->getPredicate(), RHS)); } } diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -2073,7 +2073,7 @@ // * x.1 >= 5 // * x.2 < x.1 // - // stride = [0, 5) + // stride = [0, -1) auto M = parseModule(R"( declare void @llvm.assume(i1) @@ -2088,17 +2088,45 @@ Function *F = M->getFunction("test"); AssumptionCache AC(*F); + Value *X1 = &*(F->arg_begin()); Value *X2 = &*std::next(F->arg_begin()); Instruction *I = &findInstructionByName(F, "stride.plus.one"); - ConstantRange CR1 = computeConstantRange(X2, true, &AC, I); - EXPECT_EQ(0, CR1.getLower()); - EXPECT_EQ(5, CR1.getUpper()); + ConstantRange CR1 = computeConstantRange(X1, true, &AC, I); + ConstantRange CR2 = computeConstantRange(X2, true, &AC, I); + + EXPECT_EQ(5, CR1.getLower()); + EXPECT_EQ(0, CR1.getUpper()); + + EXPECT_EQ(0, CR2.getLower()); + EXPECT_EQ(0xffffffff, CR2.getUpper()); // Check the depth cutoff results in a conservative result (full set) by // passing Depth == MaxDepth == 6. - ConstantRange CR2 = computeConstantRange(X2, true, &AC, I, 6); - EXPECT_TRUE(CR2.isFullSet()); + ConstantRange CR3 = computeConstantRange(X2, true, &AC, I, 6); + EXPECT_TRUE(CR3.isFullSet()); + } + { + // Assumptions: + // * x.2 <= x.1 + auto M = parseModule(R"( + declare void @llvm.assume(i1) + + define i32 @test(i32 %x.1, i32 %x.2) { + %lt = icmp ule i32 %x.2, %x.1 + call void @llvm.assume(i1 %lt) + %stride.plus.one = add nsw nuw i32 %x.1, 1 + ret i32 %stride.plus.one + })"); + Function *F = M->getFunction("test"); + + AssumptionCache AC(*F); + Value *X2 = &*std::next(F->arg_begin()); + + Instruction *I = &findInstructionByName(F, "stride.plus.one"); + ConstantRange CR1 = computeConstantRange(X2, true, &AC, I); + // If we don't know the value of x.2, we don't know the value of x.1. + EXPECT_TRUE(CR1.isFullSet()); } }