@@ -1617,21 +1617,107 @@ ConstantRange::shl(const ConstantRange &Other) const {
1617
1617
return ConstantRange::getNonEmpty (std::move (Min), std::move (Max) + 1 );
1618
1618
}
1619
1619
1620
+ static ConstantRange computeShlNUW (const ConstantRange &LHS,
1621
+ const ConstantRange &RHS) {
1622
+ unsigned BitWidth = LHS.getBitWidth ();
1623
+ bool Overflow;
1624
+ APInt LHSMin = LHS.getUnsignedMin ();
1625
+ unsigned RHSMin = RHS.getUnsignedMin ().getLimitedValue (BitWidth);
1626
+ APInt MinShl = LHSMin.ushl_ov (RHSMin, Overflow);
1627
+ if (Overflow)
1628
+ return ConstantRange::getEmpty (BitWidth);
1629
+ APInt LHSMax = LHS.getUnsignedMax ();
1630
+ unsigned RHSMax = RHS.getUnsignedMax ().getLimitedValue (BitWidth);
1631
+ APInt MaxShl = MinShl;
1632
+ unsigned MaxShAmt = LHSMax.countLeadingZeros ();
1633
+ if (RHSMin <= MaxShAmt)
1634
+ MaxShl = LHSMax << std::min (RHSMax, MaxShAmt);
1635
+ RHSMin = std::max (RHSMin, MaxShAmt + 1 );
1636
+ RHSMax = std::min (RHSMax, LHSMin.countLeadingZeros ());
1637
+ if (RHSMin <= RHSMax)
1638
+ MaxShl = APIntOps::umax (MaxShl,
1639
+ APInt::getHighBitsSet (BitWidth, BitWidth - RHSMin));
1640
+ return ConstantRange::getNonEmpty (MinShl, MaxShl + 1 );
1641
+ }
1642
+
1643
+ static ConstantRange computeShlNSWWithNNegLHS (const APInt &LHSMin,
1644
+ const APInt &LHSMax,
1645
+ unsigned RHSMin,
1646
+ unsigned RHSMax) {
1647
+ unsigned BitWidth = LHSMin.getBitWidth ();
1648
+ bool Overflow;
1649
+ APInt MinShl = LHSMin.sshl_ov (RHSMin, Overflow);
1650
+ if (Overflow)
1651
+ return ConstantRange::getEmpty (BitWidth);
1652
+ APInt MaxShl = MinShl;
1653
+ unsigned MaxShAmt = LHSMax.countLeadingZeros () - 1 ;
1654
+ if (RHSMin <= MaxShAmt)
1655
+ MaxShl = LHSMax << std::min (RHSMax, MaxShAmt);
1656
+ RHSMin = std::max (RHSMin, MaxShAmt + 1 );
1657
+ RHSMax = std::min (RHSMax, LHSMin.countLeadingZeros () - 1 );
1658
+ if (RHSMin <= RHSMax)
1659
+ MaxShl = APIntOps::umax (MaxShl,
1660
+ APInt::getBitsSet (BitWidth, RHSMin, BitWidth - 1 ));
1661
+ return ConstantRange::getNonEmpty (MinShl, MaxShl + 1 );
1662
+ }
1663
+
1664
+ static ConstantRange computeShlNSWWithNegLHS (const APInt &LHSMin,
1665
+ const APInt &LHSMax,
1666
+ unsigned RHSMin, unsigned RHSMax) {
1667
+ unsigned BitWidth = LHSMin.getBitWidth ();
1668
+ bool Overflow;
1669
+ APInt MaxShl = LHSMax.sshl_ov (RHSMin, Overflow);
1670
+ if (Overflow)
1671
+ return ConstantRange::getEmpty (BitWidth);
1672
+ APInt MinShl = MaxShl;
1673
+ unsigned MaxShAmt = LHSMin.countLeadingOnes () - 1 ;
1674
+ if (RHSMin <= MaxShAmt)
1675
+ MinShl = LHSMin.shl (std::min (RHSMax, MaxShAmt));
1676
+ RHSMin = std::max (RHSMin, MaxShAmt + 1 );
1677
+ RHSMax = std::min (RHSMax, LHSMax.countLeadingOnes () - 1 );
1678
+ if (RHSMin <= RHSMax)
1679
+ MinShl = APInt::getSignMask (BitWidth);
1680
+ return ConstantRange::getNonEmpty (MinShl, MaxShl + 1 );
1681
+ }
1682
+
1683
+ static ConstantRange computeShlNSW (const ConstantRange &LHS,
1684
+ const ConstantRange &RHS) {
1685
+ unsigned BitWidth = LHS.getBitWidth ();
1686
+ unsigned RHSMin = RHS.getUnsignedMin ().getLimitedValue (BitWidth);
1687
+ unsigned RHSMax = RHS.getUnsignedMax ().getLimitedValue (BitWidth);
1688
+ APInt LHSMin = LHS.getSignedMin ();
1689
+ APInt LHSMax = LHS.getSignedMax ();
1690
+ if (LHSMin.isNonNegative ())
1691
+ return computeShlNSWWithNNegLHS (LHSMin, LHSMax, RHSMin, RHSMax);
1692
+ else if (LHSMax.isNegative ())
1693
+ return computeShlNSWWithNegLHS (LHSMin, LHSMax, RHSMin, RHSMax);
1694
+ return computeShlNSWWithNNegLHS (APInt::getZero (BitWidth), LHSMax, RHSMin,
1695
+ RHSMax)
1696
+ .unionWith (computeShlNSWWithNegLHS (LHSMin, APInt::getAllOnes (BitWidth),
1697
+ RHSMin, RHSMax),
1698
+ ConstantRange::Signed);
1699
+ }
1700
+
1620
1701
ConstantRange ConstantRange::shlWithNoWrap (const ConstantRange &Other,
1621
1702
unsigned NoWrapKind,
1622
1703
PreferredRangeType RangeType) const {
1623
1704
if (isEmptySet () || Other.isEmptySet ())
1624
1705
return getEmpty ();
1625
1706
1626
- ConstantRange Result = shl (Other);
1627
-
1628
- if (NoWrapKind & OverflowingBinaryOperator::NoSignedWrap)
1629
- Result = Result.intersectWith (sshl_sat (Other), RangeType);
1630
-
1631
- if (NoWrapKind & OverflowingBinaryOperator::NoUnsignedWrap)
1632
- Result = Result.intersectWith (ushl_sat (Other), RangeType);
1633
-
1634
- return Result;
1707
+ switch (NoWrapKind) {
1708
+ case 0 :
1709
+ return shl (Other);
1710
+ case OverflowingBinaryOperator::NoSignedWrap:
1711
+ return computeShlNSW (*this , Other);
1712
+ case OverflowingBinaryOperator::NoUnsignedWrap:
1713
+ return computeShlNUW (*this , Other);
1714
+ case OverflowingBinaryOperator::NoSignedWrap |
1715
+ OverflowingBinaryOperator::NoUnsignedWrap:
1716
+ return computeShlNSW (*this , Other)
1717
+ .intersectWith (computeShlNUW (*this , Other), RangeType);
1718
+ default :
1719
+ llvm_unreachable (" Invalid NoWrapKind" );
1720
+ }
1635
1721
}
1636
1722
1637
1723
ConstantRange
0 commit comments