18af01573SFlorian Hahn //===- ValueLatticeTest.cpp - ScalarEvolution unit tests --------------===// 28af01573SFlorian Hahn // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 68af01573SFlorian Hahn // 78af01573SFlorian Hahn //===----------------------------------------------------------------------===// 88af01573SFlorian Hahn 98af01573SFlorian Hahn #include "llvm/Analysis/ValueLattice.h" 108af01573SFlorian Hahn #include "llvm/ADT/SmallVector.h" 118af01573SFlorian Hahn #include "llvm/IR/ConstantRange.h" 128af01573SFlorian Hahn #include "llvm/IR/Constants.h" 138af01573SFlorian Hahn #include "llvm/IR/IRBuilder.h" 148af01573SFlorian Hahn #include "llvm/IR/LLVMContext.h" 158af01573SFlorian Hahn #include "llvm/IR/Module.h" 168af01573SFlorian Hahn #include "gtest/gtest.h" 178af01573SFlorian Hahn 188af01573SFlorian Hahn namespace llvm { 198af01573SFlorian Hahn namespace { 208af01573SFlorian Hahn 218af01573SFlorian Hahn // We use this fixture to ensure that we clean up ScalarEvolution before 228af01573SFlorian Hahn // deleting the PassManager. 238af01573SFlorian Hahn class ValueLatticeTest : public testing::Test { 248af01573SFlorian Hahn protected: 258af01573SFlorian Hahn LLVMContext Context; 268af01573SFlorian Hahn Module M; 278af01573SFlorian Hahn 288af01573SFlorian Hahn ValueLatticeTest() : M("", Context) {} 298af01573SFlorian Hahn }; 308af01573SFlorian Hahn 318af01573SFlorian Hahn TEST_F(ValueLatticeTest, ValueLatticeGetters) { 328af01573SFlorian Hahn auto I32Ty = IntegerType::get(Context, 32); 338af01573SFlorian Hahn auto *C1 = ConstantInt::get(I32Ty, 1); 348af01573SFlorian Hahn 358af01573SFlorian Hahn EXPECT_TRUE(ValueLatticeElement::get(C1).isConstantRange()); 368af01573SFlorian Hahn EXPECT_TRUE( 378af01573SFlorian Hahn ValueLatticeElement::getRange({C1->getValue()}).isConstantRange()); 388af01573SFlorian Hahn EXPECT_TRUE(ValueLatticeElement::getOverdefined().isOverdefined()); 398af01573SFlorian Hahn 408af01573SFlorian Hahn auto FloatTy = Type::getFloatTy(Context); 418af01573SFlorian Hahn auto *C2 = ConstantFP::get(FloatTy, 1.1); 428af01573SFlorian Hahn EXPECT_TRUE(ValueLatticeElement::get(C2).isConstant()); 438af01573SFlorian Hahn EXPECT_TRUE(ValueLatticeElement::getNot(C2).isNotConstant()); 448af01573SFlorian Hahn } 458af01573SFlorian Hahn 46*c1943b42SFlorian Hahn TEST_F(ValueLatticeTest, MarkConstantRange) { 47*c1943b42SFlorian Hahn auto LV1 = 48*c1943b42SFlorian Hahn ValueLatticeElement::getRange({APInt(32, 10, true), APInt(32, 20, true)}); 49*c1943b42SFlorian Hahn 50*c1943b42SFlorian Hahn // Test markConstantRange() with an equal range. 51*c1943b42SFlorian Hahn EXPECT_FALSE( 52*c1943b42SFlorian Hahn LV1.markConstantRange({APInt(32, 10, true), APInt(32, 20, true)})); 53*c1943b42SFlorian Hahn 54*c1943b42SFlorian Hahn // Test markConstantRange() with supersets of existing range. 55*c1943b42SFlorian Hahn EXPECT_TRUE(LV1.markConstantRange({APInt(32, 5, true), APInt(32, 20, true)})); 56*c1943b42SFlorian Hahn EXPECT_EQ(LV1.getConstantRange().getLower().getLimitedValue(), 5U); 57*c1943b42SFlorian Hahn EXPECT_EQ(LV1.getConstantRange().getUpper().getLimitedValue(), 20U); 58*c1943b42SFlorian Hahn EXPECT_TRUE(LV1.markConstantRange({APInt(32, 5, true), APInt(32, 23, true)})); 59*c1943b42SFlorian Hahn EXPECT_EQ(LV1.getConstantRange().getLower().getLimitedValue(), 5U); 60*c1943b42SFlorian Hahn EXPECT_EQ(LV1.getConstantRange().getUpper().getLimitedValue(), 23U); 61*c1943b42SFlorian Hahn } 62*c1943b42SFlorian Hahn 638af01573SFlorian Hahn TEST_F(ValueLatticeTest, MergeIn) { 648af01573SFlorian Hahn auto I32Ty = IntegerType::get(Context, 32); 658af01573SFlorian Hahn auto *C1 = ConstantInt::get(I32Ty, 1); 668af01573SFlorian Hahn 678af01573SFlorian Hahn // Merge to lattice values with equal integer constant. 688af01573SFlorian Hahn auto LV1 = ValueLatticeElement::get(C1); 69f681413eSFlorian Hahn EXPECT_FALSE(LV1.mergeIn(ValueLatticeElement::get(C1), M.getDataLayout())); 708af01573SFlorian Hahn EXPECT_TRUE(LV1.isConstantRange()); 718af01573SFlorian Hahn EXPECT_EQ(LV1.asConstantInteger().getValue().getLimitedValue(), 1U); 728af01573SFlorian Hahn 738af01573SFlorian Hahn // Merge LV1 with different integer constant. 74f681413eSFlorian Hahn EXPECT_TRUE(LV1.mergeIn(ValueLatticeElement::get(ConstantInt::get(I32Ty, 99)), 75f681413eSFlorian Hahn M.getDataLayout())); 76f681413eSFlorian Hahn EXPECT_TRUE(LV1.isConstantRange()); 77f681413eSFlorian Hahn EXPECT_EQ(LV1.getConstantRange().getLower().getLimitedValue(), 1U); 78f681413eSFlorian Hahn EXPECT_EQ(LV1.getConstantRange().getUpper().getLimitedValue(), 100U); 79f681413eSFlorian Hahn 80f681413eSFlorian Hahn // Merge constant range with same constant range. 81f681413eSFlorian Hahn EXPECT_FALSE(LV1.mergeIn(LV1, M.getDataLayout())); 828af01573SFlorian Hahn EXPECT_TRUE(LV1.isConstantRange()); 838af01573SFlorian Hahn EXPECT_EQ(LV1.getConstantRange().getLower().getLimitedValue(), 1U); 848af01573SFlorian Hahn EXPECT_EQ(LV1.getConstantRange().getUpper().getLimitedValue(), 100U); 858af01573SFlorian Hahn 868af01573SFlorian Hahn // Merge LV1 in undefined value. 878af01573SFlorian Hahn ValueLatticeElement LV2; 88f681413eSFlorian Hahn EXPECT_TRUE(LV2.mergeIn(LV1, M.getDataLayout())); 898af01573SFlorian Hahn EXPECT_TRUE(LV1.isConstantRange()); 908af01573SFlorian Hahn EXPECT_EQ(LV1.getConstantRange().getLower().getLimitedValue(), 1U); 918af01573SFlorian Hahn EXPECT_EQ(LV1.getConstantRange().getUpper().getLimitedValue(), 100U); 928af01573SFlorian Hahn EXPECT_TRUE(LV2.isConstantRange()); 938af01573SFlorian Hahn EXPECT_EQ(LV2.getConstantRange().getLower().getLimitedValue(), 1U); 948af01573SFlorian Hahn EXPECT_EQ(LV2.getConstantRange().getUpper().getLimitedValue(), 100U); 958af01573SFlorian Hahn 96f681413eSFlorian Hahn // Merge LV1 with overdefined. 97f681413eSFlorian Hahn EXPECT_TRUE( 98f681413eSFlorian Hahn LV1.mergeIn(ValueLatticeElement::getOverdefined(), M.getDataLayout())); 99f681413eSFlorian Hahn EXPECT_TRUE(LV1.isOverdefined()); 100f681413eSFlorian Hahn 101f681413eSFlorian Hahn // Merge overdefined with overdefined. 102f681413eSFlorian Hahn EXPECT_FALSE( 103f681413eSFlorian Hahn LV1.mergeIn(ValueLatticeElement::getOverdefined(), M.getDataLayout())); 1048af01573SFlorian Hahn EXPECT_TRUE(LV1.isOverdefined()); 1058af01573SFlorian Hahn } 1068af01573SFlorian Hahn 1070b7c6422SFlorian Hahn TEST_F(ValueLatticeTest, getCompareIntegers) { 1080b7c6422SFlorian Hahn auto *I32Ty = IntegerType::get(Context, 32); 1090b7c6422SFlorian Hahn auto *I1Ty = IntegerType::get(Context, 1); 1108af01573SFlorian Hahn auto *C1 = ConstantInt::get(I32Ty, 1); 1118af01573SFlorian Hahn auto LV1 = ValueLatticeElement::get(C1); 1128af01573SFlorian Hahn 1130b7c6422SFlorian Hahn // Check getCompare for equal integer constants. 1140b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_EQ, I1Ty, LV1)->isOneValue()); 1150b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SGE, I1Ty, LV1)->isOneValue()); 1160b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SLE, I1Ty, LV1)->isOneValue()); 1170b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_NE, I1Ty, LV1)->isZeroValue()); 1180b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SLT, I1Ty, LV1)->isZeroValue()); 1190b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SGT, I1Ty, LV1)->isZeroValue()); 1208af01573SFlorian Hahn 1218af01573SFlorian Hahn auto LV2 = 1228af01573SFlorian Hahn ValueLatticeElement::getRange({APInt(32, 10, true), APInt(32, 20, true)}); 1230b7c6422SFlorian Hahn // Check getCompare with distinct integer ranges. 1240b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SLT, I1Ty, LV2)->isOneValue()); 1250b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SLE, I1Ty, LV2)->isOneValue()); 1260b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_NE, I1Ty, LV2)->isOneValue()); 1270b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_EQ, I1Ty, LV2)->isZeroValue()); 1280b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SGE, I1Ty, LV2)->isZeroValue()); 1290b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SGT, I1Ty, LV2)->isZeroValue()); 1308af01573SFlorian Hahn 1318af01573SFlorian Hahn auto LV3 = 1328af01573SFlorian Hahn ValueLatticeElement::getRange({APInt(32, 15, true), APInt(32, 19, true)}); 1330b7c6422SFlorian Hahn // Check getCompare with a subset integer ranges. 1340b7c6422SFlorian Hahn EXPECT_EQ(LV2.getCompare(CmpInst::ICMP_SLT, I1Ty, LV3), nullptr); 1350b7c6422SFlorian Hahn EXPECT_EQ(LV2.getCompare(CmpInst::ICMP_SLE, I1Ty, LV3), nullptr); 1360b7c6422SFlorian Hahn EXPECT_EQ(LV2.getCompare(CmpInst::ICMP_NE, I1Ty, LV3), nullptr); 1370b7c6422SFlorian Hahn EXPECT_EQ(LV2.getCompare(CmpInst::ICMP_EQ, I1Ty, LV3), nullptr); 1380b7c6422SFlorian Hahn EXPECT_EQ(LV2.getCompare(CmpInst::ICMP_SGE, I1Ty, LV3), nullptr); 1390b7c6422SFlorian Hahn EXPECT_EQ(LV2.getCompare(CmpInst::ICMP_SGT, I1Ty, LV3), nullptr); 1408af01573SFlorian Hahn 1418af01573SFlorian Hahn auto LV4 = 1428af01573SFlorian Hahn ValueLatticeElement::getRange({APInt(32, 15, true), APInt(32, 25, true)}); 1430b7c6422SFlorian Hahn // Check getCompare with overlapping integer ranges. 1440b7c6422SFlorian Hahn EXPECT_EQ(LV3.getCompare(CmpInst::ICMP_SLT, I1Ty, LV4), nullptr); 1450b7c6422SFlorian Hahn EXPECT_EQ(LV3.getCompare(CmpInst::ICMP_SLE, I1Ty, LV4), nullptr); 1460b7c6422SFlorian Hahn EXPECT_EQ(LV3.getCompare(CmpInst::ICMP_NE, I1Ty, LV4), nullptr); 1470b7c6422SFlorian Hahn EXPECT_EQ(LV3.getCompare(CmpInst::ICMP_EQ, I1Ty, LV4), nullptr); 1480b7c6422SFlorian Hahn EXPECT_EQ(LV3.getCompare(CmpInst::ICMP_SGE, I1Ty, LV4), nullptr); 1490b7c6422SFlorian Hahn EXPECT_EQ(LV3.getCompare(CmpInst::ICMP_SGT, I1Ty, LV4), nullptr); 1508af01573SFlorian Hahn } 1518af01573SFlorian Hahn 1520b7c6422SFlorian Hahn TEST_F(ValueLatticeTest, getCompareFloat) { 1530b7c6422SFlorian Hahn auto *FloatTy = IntegerType::getFloatTy(Context); 1540b7c6422SFlorian Hahn auto *I1Ty = IntegerType::get(Context, 1); 1558af01573SFlorian Hahn auto *C1 = ConstantFP::get(FloatTy, 1.0); 1568af01573SFlorian Hahn auto LV1 = ValueLatticeElement::get(C1); 1578af01573SFlorian Hahn auto LV2 = ValueLatticeElement::get(C1); 1588af01573SFlorian Hahn 1590b7c6422SFlorian Hahn // Check getCompare for equal floating point constants. 1600b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::FCMP_OEQ, I1Ty, LV2)->isOneValue()); 1610b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::FCMP_OGE, I1Ty, LV2)->isOneValue()); 1620b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::FCMP_OLE, I1Ty, LV2)->isOneValue()); 1630b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::FCMP_ONE, I1Ty, LV2)->isZeroValue()); 1640b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::FCMP_OLT, I1Ty, LV2)->isZeroValue()); 1650b7c6422SFlorian Hahn EXPECT_TRUE(LV1.getCompare(CmpInst::FCMP_OGT, I1Ty, LV2)->isZeroValue()); 1668af01573SFlorian Hahn 167f681413eSFlorian Hahn EXPECT_TRUE( 1688af01573SFlorian Hahn LV1.mergeIn(ValueLatticeElement::get(ConstantFP::get(FloatTy, 2.2)), 169f681413eSFlorian Hahn M.getDataLayout())); 1700b7c6422SFlorian Hahn EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OEQ, I1Ty, LV2), nullptr); 1710b7c6422SFlorian Hahn EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OGE, I1Ty, LV2), nullptr); 1720b7c6422SFlorian Hahn EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OLE, I1Ty, LV2), nullptr); 1730b7c6422SFlorian Hahn EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_ONE, I1Ty, LV2), nullptr); 1740b7c6422SFlorian Hahn EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OLT, I1Ty, LV2), nullptr); 1750b7c6422SFlorian Hahn EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OGT, I1Ty, LV2), nullptr); 1760b7c6422SFlorian Hahn } 1770b7c6422SFlorian Hahn 1780b7c6422SFlorian Hahn TEST_F(ValueLatticeTest, getCompareUndef) { 1790b7c6422SFlorian Hahn auto *I32Ty = IntegerType::get(Context, 32); 1800b7c6422SFlorian Hahn auto *I1Ty = IntegerType::get(Context, 1); 1810b7c6422SFlorian Hahn 1820b7c6422SFlorian Hahn auto LV1 = ValueLatticeElement::get(UndefValue::get(I32Ty)); 1830b7c6422SFlorian Hahn auto LV2 = 1840b7c6422SFlorian Hahn ValueLatticeElement::getRange({APInt(32, 10, true), APInt(32, 20, true)}); 1850b7c6422SFlorian Hahn EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::ICMP_SLT, I1Ty, LV2))); 1860b7c6422SFlorian Hahn EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::ICMP_SLE, I1Ty, LV2))); 1870b7c6422SFlorian Hahn EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::ICMP_NE, I1Ty, LV2))); 1880b7c6422SFlorian Hahn EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::ICMP_EQ, I1Ty, LV2))); 1890b7c6422SFlorian Hahn EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::ICMP_SGE, I1Ty, LV2))); 1900b7c6422SFlorian Hahn EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::ICMP_SGT, I1Ty, LV2))); 1910b7c6422SFlorian Hahn 1920b7c6422SFlorian Hahn auto *FloatTy = IntegerType::getFloatTy(Context); 1930b7c6422SFlorian Hahn auto LV3 = ValueLatticeElement::get(ConstantFP::get(FloatTy, 1.0)); 1940b7c6422SFlorian Hahn EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::FCMP_OEQ, I1Ty, LV3))); 1950b7c6422SFlorian Hahn EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::FCMP_OGE, I1Ty, LV3))); 1960b7c6422SFlorian Hahn EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::FCMP_OLE, I1Ty, LV3))); 1970b7c6422SFlorian Hahn EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::FCMP_ONE, I1Ty, LV3))); 1980b7c6422SFlorian Hahn EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::FCMP_OLT, I1Ty, LV3))); 1990b7c6422SFlorian Hahn EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::FCMP_OGT, I1Ty, LV3))); 2008af01573SFlorian Hahn } 2018af01573SFlorian Hahn 2028af01573SFlorian Hahn } // end anonymous namespace 2038af01573SFlorian Hahn } // end namespace llvm 204