static bool processAdd(BinaryOperator *AddOp, LazyValueInfo *LVI) { typedef OverflowingBinaryOperator OBO; if (DontProcessAdds) return false; if (AddOp->getType()->isVectorTy() || hasLocalDefs(AddOp)) return false; bool NSW = AddOp->hasNoSignedWrap(); bool NUW = AddOp->hasNoUnsignedWrap(); if (NSW && NUW) return false; BasicBlock *BB = AddOp->getParent(); Value *LHS = AddOp->getOperand(0); Value *RHS = AddOp->getOperand(1); ConstantRange LRange = LVI->getConstantRange(LHS, BB, AddOp); // Initialize RRange only if we need it. If we know that guaranteed no wrap // range for the given LHS range is empty don't spend time calculating the // range for the RHS. Optional<ConstantRange> RRange; auto LazyRRange = [&] () { if (!RRange) RRange = LVI->getConstantRange(RHS, BB, AddOp); return RRange.getValue(); }; bool Changed = false; if (!NUW) { ConstantRange NUWRange = LRange.makeGuaranteedNoWrapRegion(BinaryOperator::Add, LRange, OBO::NoUnsignedWrap); if (!NUWRange.isEmptySet()) { bool NewNUW = NUWRange.contains(LazyRRange()); AddOp->setHasNoUnsignedWrap(NewNUW); Changed |= NewNUW; } } if (!NSW) { ConstantRange NSWRange = LRange.makeGuaranteedNoWrapRegion(BinaryOperator::Add, LRange, OBO::NoSignedWrap); if (!NSWRange.isEmptySet()) { bool NewNSW = NSWRange.contains(LazyRRange()); AddOp->setHasNoSignedWrap(NewNSW); Changed |= NewNSW; } } return Changed; }
TEST(InterpreterTests, KBCRReduction) { ConstantRange CR(WIDTH, /*isFullSet=*/false); KnownBits KB(WIDTH); do { do { KnownBits CalculatedKB = KB; ConstantRange CalculatedCR = CR; improveKBCR(CalculatedKB, CalculatedCR); KnownBits ExhaustiveKB = KB; ConstantRange ExhaustiveCR = CR; TestingUtil::exhaustiveKBCRReduction(ExhaustiveKB, ExhaustiveCR); if (KnownBitsAnalysis::isConflictingKB(CalculatedKB, ExhaustiveKB)) { outs() << "Unsound!! CR KB reduction for KB\n"; outs() << "Original KB: " << KnownBitsAnalysis::knownBitsString(KB) << "\n"; outs() << "Original CR: " << CR << "\n"; outs() << "CalculatedKB: " << KnownBitsAnalysis::knownBitsString(CalculatedKB) << '\n'; outs() << "ExhaustiveKB: " << KnownBitsAnalysis::knownBitsString(ExhaustiveKB) << '\n'; ASSERT_TRUE(false); } if (!CalculatedCR.contains(ExhaustiveCR)) { outs() << "Unsound!! CR KB reduction for CR\n"; outs() << "Original KB: " << KnownBitsAnalysis::knownBitsString(KB) << "\n"; outs() << "Original CR: " << CR << "\n"; outs() << "CalculatedCR: " << CalculatedCR << '\n'; outs() << "ExhaustiveCR: " << ExhaustiveCR << '\n'; ASSERT_TRUE(false); } CR = CRTesting::nextCR(CR); } while(!CR.isEmptySet()); } while(KBTesting::nextKB(KB)); }
// See if we can prove that the given overflow intrinsic will not overflow. static bool willNotOverflow(IntrinsicInst *II, LazyValueInfo *LVI) { using OBO = OverflowingBinaryOperator; auto NoWrap = [&] (Instruction::BinaryOps BinOp, unsigned NoWrapKind) { Value *RHS = II->getOperand(1); ConstantRange RRange = LVI->getConstantRange(RHS, II->getParent(), II); ConstantRange NWRegion = ConstantRange::makeGuaranteedNoWrapRegion( BinOp, RRange, NoWrapKind); // As an optimization, do not compute LRange if we do not need it. if (NWRegion.isEmptySet()) return false; Value *LHS = II->getOperand(0); ConstantRange LRange = LVI->getConstantRange(LHS, II->getParent(), II); return NWRegion.contains(LRange); }; switch (II->getIntrinsicID()) { default: break; case Intrinsic::uadd_with_overflow: return NoWrap(Instruction::Add, OBO::NoUnsignedWrap); case Intrinsic::sadd_with_overflow: return NoWrap(Instruction::Add, OBO::NoSignedWrap); case Intrinsic::usub_with_overflow: return NoWrap(Instruction::Sub, OBO::NoUnsignedWrap); case Intrinsic::ssub_with_overflow: return NoWrap(Instruction::Sub, OBO::NoSignedWrap); } return false; }
/// getPredicateOnEdge - Determine whether the specified value comparison /// with a constant is known to be true or false on the specified CFG edge. /// Pred is a CmpInst predicate. LazyValueInfo::Tristate LazyValueInfo::getPredicateOnEdge(unsigned Pred, Value *V, Constant *C, BasicBlock *FromBB, BasicBlock *ToBB) { LVILatticeVal Result = getCache(PImpl).getValueOnEdge(V, FromBB, ToBB); // If we know the value is a constant, evaluate the conditional. Constant *Res = 0; if (Result.isConstant()) { Res = ConstantFoldCompareInstOperands(Pred, Result.getConstant(), C, TD, TLI); if (ConstantInt *ResCI = dyn_cast<ConstantInt>(Res)) return ResCI->isZero() ? False : True; return Unknown; } if (Result.isConstantRange()) { ConstantInt *CI = dyn_cast<ConstantInt>(C); if (!CI) return Unknown; ConstantRange CR = Result.getConstantRange(); if (Pred == ICmpInst::ICMP_EQ) { if (!CR.contains(CI->getValue())) return False; if (CR.isSingleElement() && CR.contains(CI->getValue())) return True; } else if (Pred == ICmpInst::ICMP_NE) { if (!CR.contains(CI->getValue())) return True; if (CR.isSingleElement() && CR.contains(CI->getValue())) return False; } // Handle more complex predicates. ConstantRange TrueValues = ICmpInst::makeConstantRange((ICmpInst::Predicate)Pred, CI->getValue()); if (TrueValues.contains(CR)) return True; if (TrueValues.inverse().contains(CR)) return False; return Unknown; } if (Result.isNotConstant()) { // If this is an equality comparison, we can try to fold it knowing that // "V != C1". if (Pred == ICmpInst::ICMP_EQ) { // !C1 == C -> false iff C1 == C. Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE, Result.getNotConstant(), C, TD, TLI); if (Res->isNullValue()) return False; } else if (Pred == ICmpInst::ICMP_NE) { // !C1 != C -> true iff C1 == C. Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE, Result.getNotConstant(), C, TD, TLI); if (Res->isNullValue()) return True; } return Unknown; } return Unknown; }
static LazyValueInfo::Tristate getPredicateResult(unsigned Pred, Constant *C, LVILatticeVal &Result, const DataLayout *DL, TargetLibraryInfo *TLI) { // If we know the value is a constant, evaluate the conditional. Constant *Res = nullptr; if (Result.isConstant()) { Res = ConstantFoldCompareInstOperands(Pred, Result.getConstant(), C, DL, TLI); if (ConstantInt *ResCI = dyn_cast<ConstantInt>(Res)) return ResCI->isZero() ? LazyValueInfo::False : LazyValueInfo::True; return LazyValueInfo::Unknown; } if (Result.isConstantRange()) { ConstantInt *CI = dyn_cast<ConstantInt>(C); if (!CI) return LazyValueInfo::Unknown; ConstantRange CR = Result.getConstantRange(); if (Pred == ICmpInst::ICMP_EQ) { if (!CR.contains(CI->getValue())) return LazyValueInfo::False; if (CR.isSingleElement() && CR.contains(CI->getValue())) return LazyValueInfo::True; } else if (Pred == ICmpInst::ICMP_NE) { if (!CR.contains(CI->getValue())) return LazyValueInfo::True; if (CR.isSingleElement() && CR.contains(CI->getValue())) return LazyValueInfo::False; } // Handle more complex predicates. ConstantRange TrueValues = ICmpInst::makeConstantRange((ICmpInst::Predicate)Pred, CI->getValue()); if (TrueValues.contains(CR)) return LazyValueInfo::True; if (TrueValues.inverse().contains(CR)) return LazyValueInfo::False; return LazyValueInfo::Unknown; } if (Result.isNotConstant()) { // If this is an equality comparison, we can try to fold it knowing that // "V != C1". if (Pred == ICmpInst::ICMP_EQ) { // !C1 == C -> false iff C1 == C. Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE, Result.getNotConstant(), C, DL, TLI); if (Res->isNullValue()) return LazyValueInfo::False; } else if (Pred == ICmpInst::ICMP_NE) { // !C1 != C -> true iff C1 == C. Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE, Result.getNotConstant(), C, DL, TLI); if (Res->isNullValue()) return LazyValueInfo::True; } return LazyValueInfo::Unknown; } return LazyValueInfo::Unknown; }