@@ -949,6 +949,7 @@ bool ConstantRange::isIntrinsicSupported(Intrinsic::ID IntrinsicID) {
949949 case Intrinsic::smax:
950950 case Intrinsic::abs:
951951 case Intrinsic::ctlz:
952+ case Intrinsic::ctpop:
952953 return true ;
953954 default :
954955 return false ;
@@ -986,6 +987,8 @@ ConstantRange ConstantRange::intrinsic(Intrinsic::ID IntrinsicID,
986987 assert (ZeroIsPoison->getBitWidth () == 1 && " Must be boolean" );
987988 return Ops[0 ].ctlz (ZeroIsPoison->getBoolValue ());
988989 }
990+ case Intrinsic::ctpop:
991+ return Ops[0 ].ctpop ();
989992 default :
990993 assert (!isIntrinsicSupported (IntrinsicID) && " Shouldn't be supported" );
991994 llvm_unreachable (" Unsupported intrinsic" );
@@ -1736,6 +1739,52 @@ ConstantRange ConstantRange::ctlz(bool ZeroIsPoison) const {
17361739 APInt (getBitWidth (), getUnsignedMin ().countl_zero () + 1 ));
17371740}
17381741
1742+ static ConstantRange getUnsignedPopCountRange (const APInt &Lower,
1743+ const APInt &Upper) {
1744+ assert (!ConstantRange (Lower, Upper).isWrappedSet () &&
1745+ " Unexpected wrapped set." );
1746+ assert (Lower != Upper && " Unexpected empty set." );
1747+ unsigned BitWidth = Lower.getBitWidth ();
1748+ if (Lower + 1 == Upper)
1749+ return ConstantRange (APInt (BitWidth, Lower.popcount ()));
1750+
1751+ APInt Max = Upper - 1 ;
1752+ // Calculate longest common prefix.
1753+ unsigned LCPLength = (Lower ^ Max).countl_zero ();
1754+ unsigned LCPPopCount = Lower.getHiBits (LCPLength).popcount ();
1755+ // If Lower is {LCP, 000...}, the minimum is the popcount of LCP.
1756+ // Otherwise, the minimum is the popcount of LCP + 1.
1757+ unsigned MinBits =
1758+ LCPPopCount + (Lower.countr_zero () < BitWidth - LCPLength ? 1 : 0 );
1759+ // If Max is {LCP, 111...}, the maximum is the popcount of LCP + (BitWidth -
1760+ // length of LCP).
1761+ // Otherwise, the minimum is the popcount of LCP + (BitWidth -
1762+ // length of LCP - 1).
1763+ unsigned MaxBits = LCPPopCount + (BitWidth - LCPLength) -
1764+ (Max.countr_one () < BitWidth - LCPLength ? 1 : 0 );
1765+ return ConstantRange (APInt (BitWidth, MinBits), APInt (BitWidth, MaxBits + 1 ));
1766+ }
1767+
1768+ ConstantRange ConstantRange::ctpop () const {
1769+ if (isEmptySet ())
1770+ return getEmpty ();
1771+
1772+ unsigned BitWidth = getBitWidth ();
1773+ APInt Zero = APInt::getZero (BitWidth);
1774+ if (isFullSet ())
1775+ return getNonEmpty (Zero, APInt (BitWidth, BitWidth + 1 ));
1776+ if (!isWrappedSet ())
1777+ return getUnsignedPopCountRange (Lower, Upper);
1778+ // The range is wrapped. We decompose it into two ranges, [0, Upper) and
1779+ // [Lower, 0).
1780+ // Handle [Lower, 0) == [Lower, Max]
1781+ ConstantRange CR1 = ConstantRange (APInt (BitWidth, Lower.countl_one ()),
1782+ APInt (BitWidth, BitWidth + 1 ));
1783+ // Handle [0, Upper)
1784+ ConstantRange CR2 = getUnsignedPopCountRange (Zero, Upper);
1785+ return CR1.unionWith (CR2);
1786+ }
1787+
17391788ConstantRange::OverflowResult ConstantRange::unsignedAddMayOverflow (
17401789 const ConstantRange &Other) const {
17411790 if (isEmptySet () || Other.isEmptySet ())
0 commit comments