Index: lib/Analysis/LazyValueInfo.cpp =================================================================== --- lib/Analysis/LazyValueInfo.cpp +++ lib/Analysis/LazyValueInfo.cpp @@ -456,6 +456,8 @@ PHINode *PN, BasicBlock *BB); bool solveBlockValueSelect(LVILatticeVal &BBLV, SelectInst *S, BasicBlock *BB); + bool getCachedConstantRange(Value *V, Instruction *BBI, BasicBlock *BB, + ConstantRange &CR); bool solveBlockValueConstantRange(LVILatticeVal &BBLV, Instruction *BBI, BasicBlock *BB); void intersectAssumeBlockValueConstantRange(Value *Val, LVILatticeVal &BBLV, @@ -669,15 +671,16 @@ return true; } - if (isa(BBI) && BBI->getType()->isIntegerTy()) { + CastInst *CI = dyn_cast(BBI); + if (CI && CI->isIntegerCast()) { if (!solveBlockValueConstantRange(Res, BBI, BB)) return false; insertResult(Val, BB, Res); return true; } - BinaryOperator *BO = dyn_cast(BBI); - if (BO && isa(BO->getOperand(1))) { + // No point looking for a ConstantRange in a non-integer BinOp like fadd + if (isa(BBI) && BBI->getType()->isIntegerTy()) { if (!solveBlockValueConstantRange(Res, BBI, BB)) return false; insertResult(Val, BB, Res); @@ -993,35 +996,50 @@ return true; } -bool LazyValueInfoCache::solveBlockValueConstantRange(LVILatticeVal &BBLV, - Instruction *BBI, - BasicBlock *BB) { - // Figure out the range of the LHS. If that fails, bail. - if (!hasBlockValue(BBI->getOperand(0), BB)) { - if (pushBlockValue(std::make_pair(BB, BBI->getOperand(0)))) - return false; - BBLV.markOverdefined(); - return true; - } - - LVILatticeVal LHSVal = getBlockValue(BBI->getOperand(0), BB); - intersectAssumeBlockValueConstantRange(BBI->getOperand(0), LHSVal, BBI); - if (!LHSVal.isConstantRange()) { - BBLV.markOverdefined(); +/// If there is a cached ConstantRange for V at instruction BBI, set CR and +/// return true, otherwise return false +bool LazyValueInfoCache::getCachedConstantRange(Value *V, + Instruction *BBI, + BasicBlock *BB, + ConstantRange &CR) { + if (hasBlockValue(V, BB)) { + LVILatticeVal LVal = getBlockValue(V, BB); + intersectAssumeBlockValueConstantRange(V, LVal, BBI); + if (LVal.isConstantRange()) + CR = LVal.getConstantRange(); + else + CR = ConstantRange(V->getType()->getIntegerBitWidth()); return true; + } else { + return false; } +} - ConstantRange LHSRange = LHSVal.getConstantRange(); - ConstantRange RHSRange(1); - IntegerType *ResultTy = cast(BBI->getType()); - if (isa(BBI)) { - if (ConstantInt *RHS = dyn_cast(BBI->getOperand(1))) { - RHSRange = ConstantRange(RHS->getValue()); +bool LazyValueInfoCache::solveBlockValueConstantRange(LVILatticeVal &BBLV, + Instruction *BBI, + BasicBlock *BB) { + ConstantRange LHSRange(1); + if (!getCachedConstantRange(BBI->getOperand(0), BBI, BB, LHSRange)) { + if (pushBlockValue(std::make_pair(BB, BBI->getOperand(0)))) { + return false; } else { BBLV.markOverdefined(); return true; } } + ConstantRange RHSRange(1); + if (isa(BBI)) { + if (!getCachedConstantRange(BBI->getOperand(1), BBI, BB, RHSRange)) { + if (pushBlockValue(std::make_pair(BB, BBI->getOperand(1)))) { + return false; + } else { + BBLV.markOverdefined(); + return true; + } + } + } + + IntegerType *ResultTy = cast(BBI->getType()); // NOTE: We're currently limited by the set of operations that ConstantRange // can evaluate symbolically. Enhancing that set will allows us to analyze