bool getValueFromFromCondition(Value *Val, ICmpInst *ICI, LVILatticeVal &Result, bool isTrueDest) { if (ICI && isa<Constant>(ICI->getOperand(1))) { if (ICI->isEquality() && ICI->getOperand(0) == Val) { // We know that V has the RHS constant if this is a true SETEQ or // false SETNE. if (isTrueDest == (ICI->getPredicate() == ICmpInst::ICMP_EQ)) Result = LVILatticeVal::get(cast<Constant>(ICI->getOperand(1))); else Result = LVILatticeVal::getNot(cast<Constant>(ICI->getOperand(1))); return true; } // Recognize the range checking idiom that InstCombine produces. // (X-C1) u< C2 --> [C1, C1+C2) ConstantInt *NegOffset = nullptr; if (ICI->getPredicate() == ICmpInst::ICMP_ULT) match(ICI->getOperand(0), m_Add(m_Specific(Val), m_ConstantInt(NegOffset))); ConstantInt *CI = dyn_cast<ConstantInt>(ICI->getOperand(1)); if (CI && (ICI->getOperand(0) == Val || NegOffset)) { // Calculate the range of values that would satisfy the comparison. ConstantRange CmpRange(CI->getValue()); ConstantRange TrueValues = ConstantRange::makeICmpRegion(ICI->getPredicate(), CmpRange); if (NegOffset) // Apply the offset from above. TrueValues = TrueValues.subtract(NegOffset->getValue()); // If we're interested in the false dest, invert the condition. if (!isTrueDest) TrueValues = TrueValues.inverse(); Result = LVILatticeVal::getRange(TrueValues); return true; } } return false; }
/// \brief Compute the value of Val on the edge BBFrom -> BBTo. Returns false if /// Val is not constrained on the edge. static bool getEdgeValueLocal(Value *Val, BasicBlock *BBFrom, BasicBlock *BBTo, LVILatticeVal &Result) { // TODO: Handle more complex conditionals. If (v == 0 || v2 < 1) is false, we // know that v != 0. if (BranchInst *BI = dyn_cast<BranchInst>(BBFrom->getTerminator())) { // If this is a conditional branch and only one successor goes to BBTo, then // we maybe able to infer something from the condition. if (BI->isConditional() && BI->getSuccessor(0) != BI->getSuccessor(1)) { bool isTrueDest = BI->getSuccessor(0) == BBTo; assert(BI->getSuccessor(!isTrueDest) == BBTo && "BBTo isn't a successor of BBFrom"); // If V is the condition of the branch itself, then we know exactly what // it is. if (BI->getCondition() == Val) { Result = LVILatticeVal::get(ConstantInt::get( Type::getInt1Ty(Val->getContext()), isTrueDest)); return true; } // If the condition of the branch is an equality comparison, we may be // able to infer the value. ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition()); if (ICI && isa<Constant>(ICI->getOperand(1))) { if (ICI->isEquality() && ICI->getOperand(0) == Val) { // We know that V has the RHS constant if this is a true SETEQ or // false SETNE. if (isTrueDest == (ICI->getPredicate() == ICmpInst::ICMP_EQ)) Result = LVILatticeVal::get(cast<Constant>(ICI->getOperand(1))); else Result = LVILatticeVal::getNot(cast<Constant>(ICI->getOperand(1))); return true; } // Recognize the range checking idiom that InstCombine produces. // (X-C1) u< C2 --> [C1, C1+C2) ConstantInt *NegOffset = 0; if (ICI->getPredicate() == ICmpInst::ICMP_ULT) match(ICI->getOperand(0), m_Add(m_Specific(Val), m_ConstantInt(NegOffset))); ConstantInt *CI = dyn_cast<ConstantInt>(ICI->getOperand(1)); if (CI && (ICI->getOperand(0) == Val || NegOffset)) { // Calculate the range of values that would satisfy the comparison. ConstantRange CmpRange(CI->getValue()); ConstantRange TrueValues = ConstantRange::makeICmpRegion(ICI->getPredicate(), CmpRange); if (NegOffset) // Apply the offset from above. TrueValues = TrueValues.subtract(NegOffset->getValue()); // If we're interested in the false dest, invert the condition. if (!isTrueDest) TrueValues = TrueValues.inverse(); Result = LVILatticeVal::getRange(TrueValues); return true; } } } } // If the edge was formed by a switch on the value, then we may know exactly // what it is. if (SwitchInst *SI = dyn_cast<SwitchInst>(BBFrom->getTerminator())) { if (SI->getCondition() != Val) return false; bool DefaultCase = SI->getDefaultDest() == BBTo; unsigned BitWidth = Val->getType()->getIntegerBitWidth(); ConstantRange EdgesVals(BitWidth, DefaultCase/*isFullSet*/); for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end(); i != e; ++i) { ConstantRange EdgeVal(i.getCaseValue()->getValue()); if (DefaultCase) { // It is possible that the default destination is the destination of // some cases. There is no need to perform difference for those cases. if (i.getCaseSuccessor() != BBTo) EdgesVals = EdgesVals.difference(EdgeVal); } else if (i.getCaseSuccessor() == BBTo) EdgesVals = EdgesVals.unionWith(EdgeVal); } Result = LVILatticeVal::getRange(EdgesVals); return true; } return false; }