[llvm] [SCCP] Add support for trunc nuw range. (PR #152990)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 11 07:38:12 PDT 2025
================
@@ -451,6 +452,69 @@ TEST_F(ConstantRangeTest, Trunc) {
EXPECT_EQ(SevenOne.truncate(2), ConstantRange(APInt(2, 3), APInt(2, 1)));
}
+TEST_F(ConstantRangeTest, TruncNuw) {
+ auto Range = [](unsigned NumBits, unsigned Lower, unsigned Upper) {
+ return ConstantRange(APInt(NumBits, Lower), APInt(NumBits, Upper));
+ };
+ // trunc([0, 4), 3->2) = full
+ EXPECT_TRUE(
+ Range(3, 0, 4).truncate(2, TruncInst::NoUnsignedWrap).isFullSet());
+ // trunc([0, 3), 3->2) = [0, 3)
+ EXPECT_EQ(Range(3, 0, 3).truncate(2, TruncInst::NoUnsignedWrap),
+ Range(2, 0, 3));
+ // trunc([1, 3), 3->2) = [1, 3)
+ EXPECT_EQ(Range(3, 1, 3).truncate(2, TruncInst::NoUnsignedWrap),
+ Range(2, 1, 3));
+ // trunc([1, 5), 3->2) = [1, 0)
+ EXPECT_EQ(Range(3, 1, 5).truncate(2, TruncInst::NoUnsignedWrap),
+ Range(2, 1, 0));
+ // trunc([4, 7), 3->2) = empty
+ EXPECT_TRUE(
+ Range(3, 4, 7).truncate(2, TruncInst::NoUnsignedWrap).isEmptySet());
+ // trunc([4, 0), 3->2) = empty
+ EXPECT_TRUE(
+ Range(3, 4, 0).truncate(2, TruncInst::NoUnsignedWrap).isEmptySet());
+ // trunc([4, 1), 3->2) = [0, 1)
+ EXPECT_EQ(Range(3, 4, 1).truncate(2, TruncInst::NoUnsignedWrap),
+ Range(2, 0, 1));
+ // trunc([3, 1), 3->2) = [3, 1)
+ EXPECT_EQ(Range(3, 3, 1).truncate(2, TruncInst::NoUnsignedWrap),
+ Range(2, 3, 1));
+ // trunc([3, 0), 3->2) = [3, 0)
+ EXPECT_EQ(Range(3, 3, 0).truncate(2, TruncInst::NoUnsignedWrap),
+ Range(2, 3, 0));
+ // trunc([1, 0), 2->1) = [1, 0)
+ EXPECT_EQ(Range(2, 1, 0).truncate(1, TruncInst::NoUnsignedWrap),
+ Range(1, 1, 0));
+ // trunc([2, 1), 2->1) = [0, 1)
+ EXPECT_EQ(Range(2, 2, 1).truncate(1, TruncInst::NoUnsignedWrap),
+ Range(1, 0, 1));
+}
+
+TEST_F(ConstantRangeTest, TruncNuwExhaustive) {
+ unsigned NumBits = 3;
+ EnumerateConstantRanges(4, [&](const ConstantRange &CR) {
----------------
nikic wrote:
Is it possible to reuse the generic TestRange function here? Would something along these lines work?
```
EnumerateConstantRanges(4, [&](const ConstantRange &CR) {
unsigned NumBits = 3;
ConstantRange Trunc = CR.truncate(NumBits, TruncInst::NoUnsignedWrap);
SmallBitVector Elems(1 << NumBits);
ForeachNumInConstantRange(CR, [&](const APInt &N) {
if (N.isIntN(NumBits))
Elems.set(ResultN->getZExtValue());
});
TestRange(Trunc, Elems, PreferSmallest, {CR});
});
```
https://github.com/llvm/llvm-project/pull/152990
More information about the llvm-commits
mailing list