@@ -949,6 +949,7 @@ bool ConstantRange::isIntrinsicSupported(Intrinsic::ID IntrinsicID) {
949
949
case Intrinsic::smax:
950
950
case Intrinsic::abs:
951
951
case Intrinsic::ctlz:
952
+ case Intrinsic::ctpop:
952
953
return true ;
953
954
default :
954
955
return false ;
@@ -986,6 +987,8 @@ ConstantRange ConstantRange::intrinsic(Intrinsic::ID IntrinsicID,
986
987
assert (ZeroIsPoison->getBitWidth () == 1 && " Must be boolean" );
987
988
return Ops[0 ].ctlz (ZeroIsPoison->getBoolValue ());
988
989
}
990
+ case Intrinsic::ctpop:
991
+ return Ops[0 ].ctpop ();
989
992
default :
990
993
assert (!isIntrinsicSupported (IntrinsicID) && " Shouldn't be supported" );
991
994
llvm_unreachable (" Unsupported intrinsic" );
@@ -1736,6 +1739,52 @@ ConstantRange ConstantRange::ctlz(bool ZeroIsPoison) const {
1736
1739
APInt (getBitWidth (), getUnsignedMin ().countl_zero () + 1 ));
1737
1740
}
1738
1741
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
+
1739
1788
ConstantRange::OverflowResult ConstantRange::unsignedAddMayOverflow (
1740
1789
const ConstantRange &Other) const {
1741
1790
if (isEmptySet () || Other.isEmptySet ())
0 commit comments