llvm.org GIT mirror llvm / 5cecfe9
[ConstantRange] Support for ashr in ConstantRange computation Extend the ConstantRange implementation to compute the range of possible values resulting from an arithmetic right shift operation. There will be a follow up patch to leverage this constant range infrastructure in LazyValueInfo. Patch by Surya Kumari Jangala! Differential Revision: https://reviews.llvm.org/D40881 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320976 91177308-0d34-0410-b5e6-96231b3b80d8 Max Kazantsev 2 years ago
3 changed file(s) with 87 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
316316 /// logical right shift of a value in this range and a value in \p Other.
317317 ConstantRange lshr(const ConstantRange &Other) const;
318318
319 /// Return a new range representing the possible values resulting from a
320 /// arithmetic right shift of a value in this range and a value in \p Other.
321 ConstantRange ashr(const ConstantRange &Other) const;
322
319323 /// Return a new range that is the logical not of the current set.
320324 ConstantRange inverse() const;
321325
679679 return shl(Other);
680680 case Instruction::LShr:
681681 return lshr(Other);
682 case Instruction::AShr:
683 return ashr(Other);
682684 case Instruction::And:
683685 return binaryAnd(Other);
684686 case Instruction::Or:
945947 return ConstantRange(std::move(min), std::move(max));
946948 }
947949
950 ConstantRange
951 ConstantRange::ashr(const ConstantRange &Other) const {
952 if (isEmptySet() || Other.isEmptySet())
953 return ConstantRange(getBitWidth(), /*isFullSet=*/false);
954
955 // May straddle zero, so handle both positive and negative cases.
956 // 'PosMax' is the upper bound of the result of the ashr
957 // operation, when Upper of the LHS of ashr is a non-negative.
958 // number. Since ashr of a non-negative number will result in a
959 // smaller number, the Upper value of LHS is shifted right with
960 // the minimum value of 'Other' instead of the maximum value.
961 APInt PosMax = getSignedMax().ashr(Other.getUnsignedMin()) + 1;
962
963 // 'PosMin' is the lower bound of the result of the ashr
964 // operation, when Lower of the LHS is a non-negative number.
965 // Since ashr of a non-negative number will result in a smaller
966 // number, the Lower value of LHS is shifted right with the
967 // maximum value of 'Other'.
968 APInt PosMin = getSignedMin().ashr(Other.getUnsignedMax());
969
970 // 'NegMax' is the upper bound of the result of the ashr
971 // operation, when Upper of the LHS of ashr is a negative number.
972 // Since 'ashr' of a negative number will result in a bigger
973 // number, the Upper value of LHS is shifted right with the
974 // maximum value of 'Other'.
975 APInt NegMax = getSignedMax().ashr(Other.getUnsignedMax()) + 1;
976
977 // 'NegMin' is the lower bound of the result of the ashr
978 // operation, when Lower of the LHS of ashr is a negative number.
979 // Since 'ashr' of a negative number will result in a bigger
980 // number, the Lower value of LHS is shifted right with the
981 // minimum value of 'Other'.
982 APInt NegMin = getSignedMin().ashr(Other.getUnsignedMin());
983
984 APInt max, min;
985 if (getSignedMin().isNonNegative()) {
986 // Upper and Lower of LHS are non-negative.
987 min = PosMin;
988 max = PosMax;
989 } else if (getSignedMax().isNegative()) {
990 // Upper and Lower of LHS are negative.
991 min = NegMin;
992 max = NegMax;
993 } else {
994 // Upper is non-negative and Lower is negative.
995 min = NegMin;
996 max = PosMax;
997 }
998 if (min == max)
999 return ConstantRange(getBitWidth(), /*isFullSet=*/true);
1000
1001 return ConstantRange(std::move(min), std::move(max));
1002 }
1003
9481004 ConstantRange ConstantRange::inverse() const {
9491005 if (isFullSet())
9501006 return ConstantRange(getBitWidth(), /*isFullSet=*/false);
605605 EXPECT_EQ(Wrap.lshr(Wrap), Full);
606606 }
607607
608 TEST_F(ConstantRangeTest, Ashr) {
609 EXPECT_EQ(Full.ashr(Full), Full);
610 EXPECT_EQ(Full.ashr(Empty), Empty);
611 EXPECT_EQ(Full.ashr(One), ConstantRange(APInt(16, 0xffe0),
612 APInt(16, (0x7fff >> 0xa) + 1 )));
613 ConstantRange Small(APInt(16, 0xa), APInt(16, 0xb));
614 EXPECT_EQ(Full.ashr(Small), ConstantRange(APInt(16, 0xffe0),
615 APInt(16, (0x7fff >> 0xa) + 1 )));
616 EXPECT_EQ(Full.ashr(Some), ConstantRange(APInt(16, 0xffe0),
617 APInt(16, (0x7fff >> 0xa) + 1 )));
618 EXPECT_EQ(Full.ashr(Wrap), Full);
619 EXPECT_EQ(Empty.ashr(Empty), Empty);
620 EXPECT_EQ(Empty.ashr(One), Empty);
621 EXPECT_EQ(Empty.ashr(Some), Empty);
622 EXPECT_EQ(Empty.ashr(Wrap), Empty);
623 EXPECT_EQ(One.ashr(One), ConstantRange(APInt(16, 0)));
624 EXPECT_EQ(One.ashr(Some), ConstantRange(APInt(16, 0)));
625 EXPECT_EQ(One.ashr(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xb)));
626 EXPECT_EQ(Some.ashr(Some), ConstantRange(APInt(16, 0),
627 APInt(16, (0xaaa >> 0xa) + 1)));
628 EXPECT_EQ(Some.ashr(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));
629 EXPECT_EQ(Wrap.ashr(Wrap), Full);
630 ConstantRange Neg(APInt(16, 0xf3f0, true), APInt(16, 0xf7f8, true));
631 EXPECT_EQ(Neg.ashr(Small), ConstantRange(APInt(16, 0xfffc, true),
632 APInt(16, 0xfffe, true)));
633 }
634
608635 TEST(ConstantRange, MakeAllowedICmpRegion) {
609636 // PR8250
610637 ConstantRange SMax = ConstantRange(APInt::getSignedMaxValue(32));