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 };
278af01573SFlorian Hahn 
TEST_F(ValueLatticeTest,ValueLatticeGetters)288af01573SFlorian Hahn TEST_F(ValueLatticeTest, ValueLatticeGetters) {
298af01573SFlorian Hahn   auto I32Ty = IntegerType::get(Context, 32);
308af01573SFlorian Hahn   auto *C1 = ConstantInt::get(I32Ty, 1);
318af01573SFlorian Hahn 
328af01573SFlorian Hahn   EXPECT_TRUE(ValueLatticeElement::get(C1).isConstantRange());
338af01573SFlorian Hahn   EXPECT_TRUE(
348af01573SFlorian Hahn       ValueLatticeElement::getRange({C1->getValue()}).isConstantRange());
358af01573SFlorian Hahn   EXPECT_TRUE(ValueLatticeElement::getOverdefined().isOverdefined());
368af01573SFlorian Hahn 
378af01573SFlorian Hahn   auto FloatTy = Type::getFloatTy(Context);
388af01573SFlorian Hahn   auto *C2 = ConstantFP::get(FloatTy, 1.1);
398af01573SFlorian Hahn   EXPECT_TRUE(ValueLatticeElement::get(C2).isConstant());
408af01573SFlorian Hahn   EXPECT_TRUE(ValueLatticeElement::getNot(C2).isNotConstant());
418af01573SFlorian Hahn }
428af01573SFlorian Hahn 
TEST_F(ValueLatticeTest,MarkConstantRange)43c1943b42SFlorian Hahn TEST_F(ValueLatticeTest, MarkConstantRange) {
44c1943b42SFlorian Hahn   auto LV1 =
45c1943b42SFlorian Hahn       ValueLatticeElement::getRange({APInt(32, 10, true), APInt(32, 20, true)});
46c1943b42SFlorian Hahn 
47c1943b42SFlorian Hahn   // Test markConstantRange() with an equal range.
48c1943b42SFlorian Hahn   EXPECT_FALSE(
49c1943b42SFlorian Hahn       LV1.markConstantRange({APInt(32, 10, true), APInt(32, 20, true)}));
50c1943b42SFlorian Hahn 
51c1943b42SFlorian Hahn   // Test markConstantRange() with supersets of existing range.
52c1943b42SFlorian Hahn   EXPECT_TRUE(LV1.markConstantRange({APInt(32, 5, true), APInt(32, 20, true)}));
53c1943b42SFlorian Hahn   EXPECT_EQ(LV1.getConstantRange().getLower().getLimitedValue(), 5U);
54c1943b42SFlorian Hahn   EXPECT_EQ(LV1.getConstantRange().getUpper().getLimitedValue(), 20U);
55c1943b42SFlorian Hahn   EXPECT_TRUE(LV1.markConstantRange({APInt(32, 5, true), APInt(32, 23, true)}));
56c1943b42SFlorian Hahn   EXPECT_EQ(LV1.getConstantRange().getLower().getLimitedValue(), 5U);
57c1943b42SFlorian Hahn   EXPECT_EQ(LV1.getConstantRange().getUpper().getLimitedValue(), 23U);
58c1943b42SFlorian Hahn }
59c1943b42SFlorian Hahn 
TEST_F(ValueLatticeTest,MergeIn)608af01573SFlorian Hahn TEST_F(ValueLatticeTest, MergeIn) {
618af01573SFlorian Hahn   auto I32Ty = IntegerType::get(Context, 32);
628af01573SFlorian Hahn   auto *C1 = ConstantInt::get(I32Ty, 1);
638af01573SFlorian Hahn 
648af01573SFlorian Hahn   // Merge to lattice values with equal integer constant.
658af01573SFlorian Hahn   auto LV1 = ValueLatticeElement::get(C1);
66e833e583SAaron Puchert   EXPECT_FALSE(LV1.mergeIn(ValueLatticeElement::get(C1)));
678af01573SFlorian Hahn   EXPECT_TRUE(LV1.isConstantRange());
68*d152e50cSKazu Hirata   EXPECT_EQ(LV1.asConstantInteger()->getLimitedValue(), 1U);
698af01573SFlorian Hahn 
708af01573SFlorian Hahn   // Merge LV1 with different integer constant.
71e833e583SAaron Puchert   EXPECT_TRUE(
72e833e583SAaron Puchert       LV1.mergeIn(ValueLatticeElement::get(ConstantInt::get(I32Ty, 99))));
73f681413eSFlorian Hahn   EXPECT_TRUE(LV1.isConstantRange());
74f681413eSFlorian Hahn   EXPECT_EQ(LV1.getConstantRange().getLower().getLimitedValue(), 1U);
75f681413eSFlorian Hahn   EXPECT_EQ(LV1.getConstantRange().getUpper().getLimitedValue(), 100U);
76f681413eSFlorian Hahn 
77f681413eSFlorian Hahn   // Merge constant range with same constant range.
78e833e583SAaron Puchert   EXPECT_FALSE(LV1.mergeIn(LV1));
798af01573SFlorian Hahn   EXPECT_TRUE(LV1.isConstantRange());
808af01573SFlorian Hahn   EXPECT_EQ(LV1.getConstantRange().getLower().getLimitedValue(), 1U);
818af01573SFlorian Hahn   EXPECT_EQ(LV1.getConstantRange().getUpper().getLimitedValue(), 100U);
828af01573SFlorian Hahn 
838af01573SFlorian Hahn   // Merge LV1 in undefined value.
848af01573SFlorian Hahn   ValueLatticeElement LV2;
85e833e583SAaron Puchert   EXPECT_TRUE(LV2.mergeIn(LV1));
868af01573SFlorian Hahn   EXPECT_TRUE(LV1.isConstantRange());
878af01573SFlorian Hahn   EXPECT_EQ(LV1.getConstantRange().getLower().getLimitedValue(), 1U);
888af01573SFlorian Hahn   EXPECT_EQ(LV1.getConstantRange().getUpper().getLimitedValue(), 100U);
898af01573SFlorian Hahn   EXPECT_TRUE(LV2.isConstantRange());
908af01573SFlorian Hahn   EXPECT_EQ(LV2.getConstantRange().getLower().getLimitedValue(), 1U);
918af01573SFlorian Hahn   EXPECT_EQ(LV2.getConstantRange().getUpper().getLimitedValue(), 100U);
928af01573SFlorian Hahn 
93f681413eSFlorian Hahn   // Merge LV1 with overdefined.
94e833e583SAaron Puchert   EXPECT_TRUE(LV1.mergeIn(ValueLatticeElement::getOverdefined()));
95f681413eSFlorian Hahn   EXPECT_TRUE(LV1.isOverdefined());
96f681413eSFlorian Hahn 
97f681413eSFlorian Hahn   // Merge overdefined with overdefined.
98e833e583SAaron Puchert   EXPECT_FALSE(LV1.mergeIn(ValueLatticeElement::getOverdefined()));
998af01573SFlorian Hahn   EXPECT_TRUE(LV1.isOverdefined());
1008af01573SFlorian Hahn }
1018af01573SFlorian Hahn 
TEST_F(ValueLatticeTest,getCompareIntegers)1020b7c6422SFlorian Hahn TEST_F(ValueLatticeTest, getCompareIntegers) {
1030b7c6422SFlorian Hahn   auto *I32Ty = IntegerType::get(Context, 32);
1040b7c6422SFlorian Hahn   auto *I1Ty = IntegerType::get(Context, 1);
1058af01573SFlorian Hahn   auto *C1 = ConstantInt::get(I32Ty, 1);
1068af01573SFlorian Hahn   auto LV1 = ValueLatticeElement::get(C1);
1078af01573SFlorian Hahn 
1080b7c6422SFlorian Hahn   // Check getCompare for equal integer constants.
1090b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_EQ, I1Ty, LV1)->isOneValue());
1100b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SGE, I1Ty, LV1)->isOneValue());
1110b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SLE, I1Ty, LV1)->isOneValue());
1120b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_NE, I1Ty, LV1)->isZeroValue());
1130b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SLT, I1Ty, LV1)->isZeroValue());
1140b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SGT, I1Ty, LV1)->isZeroValue());
1158af01573SFlorian Hahn 
1168af01573SFlorian Hahn   auto LV2 =
1178af01573SFlorian Hahn       ValueLatticeElement::getRange({APInt(32, 10, true), APInt(32, 20, true)});
1180b7c6422SFlorian Hahn   // Check getCompare with distinct integer ranges.
1190b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SLT, I1Ty, LV2)->isOneValue());
1200b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SLE, I1Ty, LV2)->isOneValue());
1210b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_NE, I1Ty, LV2)->isOneValue());
1220b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_EQ, I1Ty, LV2)->isZeroValue());
1230b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SGE, I1Ty, LV2)->isZeroValue());
1240b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::ICMP_SGT, I1Ty, LV2)->isZeroValue());
1258af01573SFlorian Hahn 
1268af01573SFlorian Hahn   auto LV3 =
1278af01573SFlorian Hahn       ValueLatticeElement::getRange({APInt(32, 15, true), APInt(32, 19, true)});
1280b7c6422SFlorian Hahn   // Check getCompare with a subset integer ranges.
1290b7c6422SFlorian Hahn   EXPECT_EQ(LV2.getCompare(CmpInst::ICMP_SLT, I1Ty, LV3), nullptr);
1300b7c6422SFlorian Hahn   EXPECT_EQ(LV2.getCompare(CmpInst::ICMP_SLE, I1Ty, LV3), nullptr);
1310b7c6422SFlorian Hahn   EXPECT_EQ(LV2.getCompare(CmpInst::ICMP_NE, I1Ty, LV3), nullptr);
1320b7c6422SFlorian Hahn   EXPECT_EQ(LV2.getCompare(CmpInst::ICMP_EQ, I1Ty, LV3), nullptr);
1330b7c6422SFlorian Hahn   EXPECT_EQ(LV2.getCompare(CmpInst::ICMP_SGE, I1Ty, LV3), nullptr);
1340b7c6422SFlorian Hahn   EXPECT_EQ(LV2.getCompare(CmpInst::ICMP_SGT, I1Ty, LV3), nullptr);
1358af01573SFlorian Hahn 
1368af01573SFlorian Hahn   auto LV4 =
1378af01573SFlorian Hahn       ValueLatticeElement::getRange({APInt(32, 15, true), APInt(32, 25, true)});
1380b7c6422SFlorian Hahn   // Check getCompare with overlapping integer ranges.
1390b7c6422SFlorian Hahn   EXPECT_EQ(LV3.getCompare(CmpInst::ICMP_SLT, I1Ty, LV4), nullptr);
1400b7c6422SFlorian Hahn   EXPECT_EQ(LV3.getCompare(CmpInst::ICMP_SLE, I1Ty, LV4), nullptr);
1410b7c6422SFlorian Hahn   EXPECT_EQ(LV3.getCompare(CmpInst::ICMP_NE, I1Ty, LV4), nullptr);
1420b7c6422SFlorian Hahn   EXPECT_EQ(LV3.getCompare(CmpInst::ICMP_EQ, I1Ty, LV4), nullptr);
1430b7c6422SFlorian Hahn   EXPECT_EQ(LV3.getCompare(CmpInst::ICMP_SGE, I1Ty, LV4), nullptr);
1440b7c6422SFlorian Hahn   EXPECT_EQ(LV3.getCompare(CmpInst::ICMP_SGT, I1Ty, LV4), nullptr);
1458af01573SFlorian Hahn }
1468af01573SFlorian Hahn 
TEST_F(ValueLatticeTest,getCompareFloat)1470b7c6422SFlorian Hahn TEST_F(ValueLatticeTest, getCompareFloat) {
1480b7c6422SFlorian Hahn   auto *FloatTy = IntegerType::getFloatTy(Context);
1490b7c6422SFlorian Hahn   auto *I1Ty = IntegerType::get(Context, 1);
1508af01573SFlorian Hahn   auto *C1 = ConstantFP::get(FloatTy, 1.0);
1518af01573SFlorian Hahn   auto LV1 = ValueLatticeElement::get(C1);
1528af01573SFlorian Hahn   auto LV2 = ValueLatticeElement::get(C1);
1538af01573SFlorian Hahn 
1540b7c6422SFlorian Hahn   // Check getCompare for equal floating point constants.
1550b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::FCMP_OEQ, I1Ty, LV2)->isOneValue());
1560b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::FCMP_OGE, I1Ty, LV2)->isOneValue());
1570b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::FCMP_OLE, I1Ty, LV2)->isOneValue());
1580b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::FCMP_ONE, I1Ty, LV2)->isZeroValue());
1590b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::FCMP_OLT, I1Ty, LV2)->isZeroValue());
1600b7c6422SFlorian Hahn   EXPECT_TRUE(LV1.getCompare(CmpInst::FCMP_OGT, I1Ty, LV2)->isZeroValue());
1618af01573SFlorian Hahn 
162f681413eSFlorian Hahn   EXPECT_TRUE(
163e833e583SAaron Puchert       LV1.mergeIn(ValueLatticeElement::get(ConstantFP::get(FloatTy, 2.2))));
1640b7c6422SFlorian Hahn   EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OEQ, I1Ty, LV2), nullptr);
1650b7c6422SFlorian Hahn   EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OGE, I1Ty, LV2), nullptr);
1660b7c6422SFlorian Hahn   EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OLE, I1Ty, LV2), nullptr);
1670b7c6422SFlorian Hahn   EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_ONE, I1Ty, LV2), nullptr);
1680b7c6422SFlorian Hahn   EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OLT, I1Ty, LV2), nullptr);
1690b7c6422SFlorian Hahn   EXPECT_EQ(LV1.getCompare(CmpInst::FCMP_OGT, I1Ty, LV2), nullptr);
1700b7c6422SFlorian Hahn }
1710b7c6422SFlorian Hahn 
TEST_F(ValueLatticeTest,getCompareUndef)1720b7c6422SFlorian Hahn TEST_F(ValueLatticeTest, getCompareUndef) {
1730b7c6422SFlorian Hahn   auto *I32Ty = IntegerType::get(Context, 32);
1740b7c6422SFlorian Hahn   auto *I1Ty = IntegerType::get(Context, 1);
1750b7c6422SFlorian Hahn 
1760b7c6422SFlorian Hahn   auto LV1 = ValueLatticeElement::get(UndefValue::get(I32Ty));
1770b7c6422SFlorian Hahn   auto LV2 =
1780b7c6422SFlorian Hahn       ValueLatticeElement::getRange({APInt(32, 10, true), APInt(32, 20, true)});
1790b7c6422SFlorian Hahn   EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::ICMP_SLT, I1Ty, LV2)));
1800b7c6422SFlorian Hahn   EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::ICMP_SLE, I1Ty, LV2)));
1810b7c6422SFlorian Hahn   EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::ICMP_NE, I1Ty, LV2)));
1820b7c6422SFlorian Hahn   EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::ICMP_EQ, I1Ty, LV2)));
1830b7c6422SFlorian Hahn   EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::ICMP_SGE, I1Ty, LV2)));
1840b7c6422SFlorian Hahn   EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::ICMP_SGT, I1Ty, LV2)));
1850b7c6422SFlorian Hahn 
1860b7c6422SFlorian Hahn   auto *FloatTy = IntegerType::getFloatTy(Context);
1870b7c6422SFlorian Hahn   auto LV3 = ValueLatticeElement::get(ConstantFP::get(FloatTy, 1.0));
1880b7c6422SFlorian Hahn   EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::FCMP_OEQ, I1Ty, LV3)));
1890b7c6422SFlorian Hahn   EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::FCMP_OGE, I1Ty, LV3)));
1900b7c6422SFlorian Hahn   EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::FCMP_OLE, I1Ty, LV3)));
1910b7c6422SFlorian Hahn   EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::FCMP_ONE, I1Ty, LV3)));
1920b7c6422SFlorian Hahn   EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::FCMP_OLT, I1Ty, LV3)));
1930b7c6422SFlorian Hahn   EXPECT_TRUE(isa<UndefValue>(LV1.getCompare(CmpInst::FCMP_OGT, I1Ty, LV3)));
1948af01573SFlorian Hahn }
1958af01573SFlorian Hahn 
1968af01573SFlorian Hahn } // end anonymous namespace
1978af01573SFlorian Hahn } // end namespace llvm
198