diff --git a/unittests/Analysis/ValueTrackingTest.cpp b/unittests/Analysis/ValueTrackingTest.cpp index 721a342040b..e9d53efbf76 100644 --- a/unittests/Analysis/ValueTrackingTest.cpp +++ b/unittests/Analysis/ValueTrackingTest.cpp @@ -67,6 +67,9 @@ protected: A = findInstructionByNameOrNull(F, "A"); ASSERT_TRUE(A) << "@test must have an instruction %A"; + A2 = findInstructionByNameOrNull(F, "A2"); + A3 = findInstructionByNameOrNull(F, "A3"); + A4 = findInstructionByNameOrNull(F, "A4"); CxtI = findInstructionByNameOrNull(F, "CxtI"); CxtI2 = findInstructionByNameOrNull(F, "CxtI2"); @@ -77,6 +80,8 @@ protected: std::unique_ptr M; Function *F = nullptr; Instruction *A = nullptr; + // Instructions (optional) + Instruction *A2 = nullptr, *A3 = nullptr, *A4 = nullptr; // Context instructions (optional) Instruction *CxtI = nullptr, *CxtI2 = nullptr, *CxtI3 = nullptr; @@ -1004,6 +1009,68 @@ TEST_F(ComputeKnownBitsTest, ComputeKnownMulBits) { expectKnownBits(/*zero*/ 95u, /*one*/ 32u); } +TEST_F(ValueTrackingTest, KnownNonZeroFromDomCond) { + parseAssembly(R"( + declare i8* @f_i8() + define void @test(i1 %c) { + %A = call i8* @f_i8() + %B = call i8* @f_i8() + %c1 = icmp ne i8* %A, null + %cond = and i1 %c1, %c + br i1 %cond, label %T, label %Q + T: + %CxtI = add i32 0, 0 + ret void + Q: + %CxtI2 = add i32 0, 0 + ret void + } + )"); + AssumptionCache AC(*F); + DominatorTree DT(*F); + DataLayout DL = M->getDataLayout(); + EXPECT_EQ(isKnownNonZero(A, DL, 0, &AC, CxtI, &DT), true); + EXPECT_EQ(isKnownNonZero(A, DL, 0, &AC, CxtI2, &DT), false); +} + +TEST_F(ValueTrackingTest, IsImpliedConditionAnd) { + parseAssembly(R"( + define void @test(i32 %x, i32 %y) { + %c1 = icmp ult i32 %x, 10 + %c2 = icmp ult i32 %y, 15 + %A = and i1 %c1, %c2 + ; x < 10 /\ y < 15 + %A2 = icmp ult i32 %x, 20 + %A3 = icmp uge i32 %y, 20 + %A4 = icmp ult i32 %x, 5 + ret void + } + )"); + DataLayout DL = M->getDataLayout(); + EXPECT_EQ(isImpliedCondition(A, A2, DL), true); + EXPECT_EQ(isImpliedCondition(A, A3, DL), false); + EXPECT_EQ(isImpliedCondition(A, A4, DL), None); +} + +TEST_F(ValueTrackingTest, IsImpliedConditionOr) { + parseAssembly(R"( + define void @test(i32 %x, i32 %y) { + %c1 = icmp ult i32 %x, 10 + %c2 = icmp ult i32 %y, 15 + %A = or i1 %c1, %c2 ; negated + ; x >= 10 /\ y >= 15 + %A2 = icmp ult i32 %x, 5 + %A3 = icmp uge i32 %y, 10 + %A4 = icmp ult i32 %x, 15 + ret void + } + )"); + DataLayout DL = M->getDataLayout(); + EXPECT_EQ(isImpliedCondition(A, A2, DL, false), false); + EXPECT_EQ(isImpliedCondition(A, A3, DL, false), true); + EXPECT_EQ(isImpliedCondition(A, A4, DL, false), None); +} + TEST_F(ComputeKnownBitsTest, KnownNonZeroShift) { // %q is known nonzero without known bits. // Because %q is nonzero, %A[0] is known to be zero.