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