// Turn all [A, B] ranges to [-B, -A]. Ranges [MIN, B] are turned to range set // [MIN, MIN] U [-B, MAX], when MIN and MAX are the minimal and the maximal // signed values of the type. RangeSet RangeSet::Negate(BasicValueFactory &BV, Factory &F) const { PrimRangeSet newRanges = F.getEmptySet(); for (iterator i = begin(), e = end(); i != e; ++i) { const llvm::APSInt &from = i->From(), &to = i->To(); const llvm::APSInt &newTo = (from.isMinSignedValue() ? BV.getMaxValue(from) : BV.getValue(- from)); if (to.isMaxSignedValue() && !newRanges.isEmpty() && newRanges.begin()->From().isMinSignedValue()) { assert(newRanges.begin()->To().isMinSignedValue() && "Ranges should not overlap"); assert(!from.isMinSignedValue() && "Ranges should not overlap"); const llvm::APSInt &newFrom = newRanges.begin()->From(); newRanges = F.add(F.remove(newRanges, *newRanges.begin()), Range(newFrom, newTo)); } else if (!to.isMinSignedValue()) { const llvm::APSInt &newFrom = BV.getValue(- to); newRanges = F.add(newRanges, Range(newFrom, newTo)); } if (from.isMinSignedValue()) { newRanges = F.add(newRanges, Range(BV.getMinValue(from), BV.getMinValue(from))); } } return newRanges; }
/// Apply implicit constraints for bitwise OR- and AND-. /// For unsigned types, bitwise OR with a constant always returns /// a value greater-or-equal than the constant, and bitwise AND /// returns a value less-or-equal then the constant. /// /// Pattern matches the expression \p Sym against those rule, /// and applies the required constraints. /// \p Input Previously established expression range set static RangeSet applyBitwiseConstraints( BasicValueFactory &BV, RangeSet::Factory &F, RangeSet Input, const SymIntExpr* SIE) { QualType T = SIE->getType(); bool IsUnsigned = T->isUnsignedIntegerType(); const llvm::APSInt &RHS = SIE->getRHS(); const llvm::APSInt &Zero = BV.getAPSIntType(T).getZeroValue(); BinaryOperator::Opcode Operator = SIE->getOpcode(); // For unsigned types, the output of bitwise-or is bigger-or-equal than RHS. if (Operator == BO_Or && IsUnsigned) return Input.Intersect(BV, F, RHS, BV.getMaxValue(T)); // Bitwise-or with a non-zero constant is always non-zero. if (Operator == BO_Or && RHS != Zero) return assumeNonZero(BV, F, SIE, Input); // For unsigned types, or positive RHS, // bitwise-and output is always smaller-or-equal than RHS (assuming two's // complement representation of signed types). if (Operator == BO_And && (IsUnsigned || RHS >= Zero)) return Input.Intersect(BV, F, BV.getMinValue(T), RHS); return Input; }
// Returns a set containing the values in the receiving set, intersected with // the closed range [Lower, Upper]. Unlike the Range type, this range uses // modular arithmetic, corresponding to the common treatment of C integer // overflow. Thus, if the Lower bound is greater than the Upper bound, the // range is taken to wrap around. This is equivalent to taking the // intersection with the two ranges [Min, Upper] and [Lower, Max], // or, alternatively, /removing/ all integers between Upper and Lower. RangeSet RangeSet::Intersect(BasicValueFactory &BV, Factory &F, llvm::APSInt Lower, llvm::APSInt Upper) const { if (!pin(Lower, Upper)) return F.getEmptySet(); PrimRangeSet newRanges = F.getEmptySet(); PrimRangeSet::iterator i = begin(), e = end(); if (Lower <= Upper) IntersectInRange(BV, F, Lower, Upper, newRanges, i, e); else { // The order of the next two statements is important! // IntersectInRange() does not reset the iteration state for i and e. // Therefore, the lower range most be handled first. IntersectInRange(BV, F, BV.getMinValue(Upper), Upper, newRanges, i, e); IntersectInRange(BV, F, Lower, BV.getMaxValue(Lower), newRanges, i, e); } return newRanges; }