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