/// unionWith - Return the range that results from the union of this range with /// another range. The resultant range is guaranteed to include the elements of /// both sets, but may contain more. For example, [3, 9) union [12,15) is /// [3, 15), which includes 9, 10, and 11, which were not included in either /// set before. /// ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const { assert(getBitWidth() == CR.getBitWidth() && "ConstantRange types don't agree!"); if ( isFullSet() || CR.isEmptySet()) return *this; if (CR.isFullSet() || isEmptySet()) return CR; if (!isWrappedSet() && CR.isWrappedSet()) return CR.unionWith(*this); if (!isWrappedSet() && !CR.isWrappedSet()) { if (CR.Upper.ult(Lower) || Upper.ult(CR.Lower)) { // If the two ranges are disjoint, find the smaller gap and bridge it. APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper; if (d1.ult(d2)) return ConstantRange(Lower, CR.Upper); return ConstantRange(CR.Lower, Upper); } APInt L = Lower, U = Upper; if (CR.Lower.ult(L)) L = CR.Lower; if ((CR.Upper - 1).ugt(U - 1)) U = CR.Upper; if (L == 0 && U == 0) return ConstantRange(getBitWidth()); return ConstantRange(L, U); } if (!CR.isWrappedSet()) { // ------U L----- and ------U L----- : this // L--U L--U : CR if (CR.Upper.ule(Upper) || CR.Lower.uge(Lower)) return *this; // ------U L----- : this // L---------U : CR if (CR.Lower.ule(Upper) && Lower.ule(CR.Upper)) return ConstantRange(getBitWidth()); // ----U L---- : this // L---U : CR // <d1> <d2> if (Upper.ule(CR.Lower) && CR.Upper.ule(Lower)) { APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper; if (d1.ult(d2)) return ConstantRange(Lower, CR.Upper); return ConstantRange(CR.Lower, Upper); } // ----U L----- : this // L----U : CR if (Upper.ult(CR.Lower) && Lower.ult(CR.Upper)) return ConstantRange(CR.Lower, Upper); // ------U L---- : this // L-----U : CR assert(CR.Lower.ult(Upper) && CR.Upper.ult(Lower) && "ConstantRange::unionWith missed a case with one range wrapped"); return ConstantRange(Lower, CR.Upper); } // ------U L---- and ------U L---- : this // -U L----------- and ------------U L : CR if (CR.Lower.ule(Upper) || Lower.ule(CR.Upper)) return ConstantRange(getBitWidth()); APInt L = Lower, U = Upper; if (CR.Upper.ugt(U)) U = CR.Upper; if (CR.Lower.ult(L)) L = CR.Lower; return ConstantRange(L, U); }
/// unionWith - Return the range that results from the union of this range with /// another range. The resultant range is guaranteed to include the elements of /// both sets, but may contain more. For example, [3, 9) union [12,15) is /// [3, 15), which includes 9, 10, and 11, which were not included in either /// set before. /// ConstantRange ConstantRange::unionWith(const ConstantRange &CR) const { assert(getBitWidth() == CR.getBitWidth() && "ConstantRange types don't agree!"); if ( isFullSet() || CR.isEmptySet()) return *this; if (CR.isFullSet() || isEmptySet()) return CR; if (!isWrappedSet() && CR.isWrappedSet()) return CR.unionWith(*this); APInt L = Lower, U = Upper; if (!isWrappedSet() && !CR.isWrappedSet()) { if (CR.Lower.ult(L)) L = CR.Lower; if (CR.Upper.ugt(U)) U = CR.Upper; } if (isWrappedSet() && !CR.isWrappedSet()) { if ((CR.Lower.ult(Upper) && CR.Upper.ult(Upper)) || (CR.Lower.ugt(Lower) && CR.Upper.ugt(Lower))) { return *this; } if (CR.Lower.ule(Upper) && Lower.ule(CR.Upper)) { return ConstantRange(getBitWidth()); } if (CR.Lower.ule(Upper) && CR.Upper.ule(Lower)) { APInt d1 = CR.Upper - Upper, d2 = Lower - CR.Upper; if (d1.ult(d2)) { U = CR.Upper; } else { L = CR.Upper; } } if (Upper.ult(CR.Lower) && CR.Upper.ult(Lower)) { APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Upper; if (d1.ult(d2)) { U = CR.Lower + 1; } else { L = CR.Upper - 1; } } if (Upper.ult(CR.Lower) && Lower.ult(CR.Upper)) { APInt d1 = CR.Lower - Upper, d2 = Lower - CR.Lower; if (d1.ult(d2)) { U = CR.Lower + 1; } else { L = CR.Lower; } } } if (isWrappedSet() && CR.isWrappedSet()) { if (Lower.ult(CR.Upper) || CR.Lower.ult(Upper)) return ConstantRange(getBitWidth()); if (CR.Upper.ugt(U)) { U = CR.Upper; } if (CR.Lower.ult(L)) { L = CR.Lower; } if (L == U) return ConstantRange(getBitWidth()); } return ConstantRange(L, U); }