diff --git a/llvm/include/llvm/Analysis/ValueLattice.h b/llvm/include/llvm/Analysis/ValueLattice.h --- a/llvm/include/llvm/Analysis/ValueLattice.h +++ b/llvm/include/llvm/Analysis/ValueLattice.h @@ -140,6 +140,7 @@ } bool isUndefined() const { return Tag == undefined; } + bool isUnknown() const { return Tag == undefined; } bool isConstant() const { return Tag == constant; } bool isNotConstant() const { return Tag == notconstant; } bool isConstantRange() const { return Tag == constantrange; } @@ -170,71 +171,77 @@ return None; } -private: - void markOverdefined() { + bool markOverdefined() { if (isOverdefined()) - return; + return false; if (isConstant() || isNotConstant()) ConstVal = nullptr; if (isConstantRange()) Range.~ConstantRange(); Tag = overdefined; + return true; } - void markConstant(Constant *V) { + bool markConstant(Constant *V) { + if (isa(V)) + return false; + assert(V && "Marking constant with NULL"); - if (ConstantInt *CI = dyn_cast(V)) { - markConstantRange(ConstantRange(CI->getValue())); - return; + + if (isConstant()) { + assert(getConstant() == V && "Marking constant with different value"); + return false; } - if (isa(V)) - return; - assert((!isConstant() || getConstant() == V) && - "Marking constant with different value"); + if (ConstantInt *CI = dyn_cast(V)) + return markConstantRange(ConstantRange(CI->getValue())); + assert(isUndefined()); Tag = constant; ConstVal = V; + return true; } - void markNotConstant(Constant *V) { + bool markNotConstant(Constant *V) { assert(V && "Marking constant with NULL"); - if (ConstantInt *CI = dyn_cast(V)) { - markConstantRange(ConstantRange(CI->getValue() + 1, CI->getValue())); - return; - } + if (ConstantInt *CI = dyn_cast(V)) + return markConstantRange( + ConstantRange(CI->getValue() + 1, CI->getValue())); + if (isa(V)) - return; + return false; - assert((!isConstant() || getConstant() != V) && - "Marking constant !constant with same value"); - assert((!isNotConstant() || getNotConstant() == V) && - "Marking !constant with different value"); - assert(isUndefined() || isConstant()); + if (isNotConstant()) { + assert(getNotConstant() == V && "Marking !constant with different value"); + return false; + } + + assert(isUndefined()); Tag = notconstant; ConstVal = V; + return true; } - void markConstantRange(ConstantRange NewR) { + bool markConstantRange(ConstantRange NewR) { if (isConstantRange()) { if (NewR.isEmptySet()) markOverdefined(); else { + assert(getConstantRange().difference(NewR).isEmptySet()); Range = std::move(NewR); } - return; + return true; } assert(isUndefined()); if (NewR.isEmptySet()) - markOverdefined(); - else { - Tag = constantrange; - new (&Range) ConstantRange(std::move(NewR)); - } + return markOverdefined(); + + Tag = constantrange; + new (&Range) ConstantRange(std::move(NewR)); + return true; } -public: /// Updates this object to approximate both this object and RHS. Returns /// true if this object has been changed. bool mergeIn(const ValueLatticeElement &RHS, const DataLayout &DL) { @@ -273,12 +280,11 @@ } ConstantRange NewR = getConstantRange().unionWith(RHS.getConstantRange()); if (NewR.isFullSet()) - markOverdefined(); + return markOverdefined(); else if (NewR == getConstantRange()) return false; else - markConstantRange(std::move(NewR)); - return true; + return markConstantRange(std::move(NewR)); } /// Compares this symbolic value with Other using Pred and returns either @@ -292,13 +298,18 @@ if (isConstant() && Other.isConstant()) return ConstantExpr::getCompare(Pred, getConstant(), Other.getConstant()); - // Integer constants are represented as ConstantRanges with single - // elements. - if (!isConstantRange() || !Other.isConstantRange()) + ConstantRange CR = ConstantRange::getEmpty(1); + if (isConstantRange()) + CR = getConstantRange(); + else + return nullptr; + + ConstantRange OtherCR = ConstantRange::getEmpty(1); + if (Other.isConstantRange()) + OtherCR = Other.getConstantRange(); + else return nullptr; - const auto &CR = getConstantRange(); - const auto &OtherCR = Other.getConstantRange(); if (ConstantRange::makeSatisfyingICmpRegion(Pred, OtherCR).contains(CR)) return ConstantInt::getTrue(Ty); if (ConstantRange::makeSatisfyingICmpRegion(