diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
commit | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch) | |
tree | 4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/Analysis/LazyValueInfo.cpp | |
parent | 7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff) |
Notes
Diffstat (limited to 'llvm/lib/Analysis/LazyValueInfo.cpp')
-rw-r--r-- | llvm/lib/Analysis/LazyValueInfo.cpp | 65 |
1 files changed, 47 insertions, 18 deletions
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp index 96722f32e3550..bad2de9e5f5e0 100644 --- a/llvm/lib/Analysis/LazyValueInfo.cpp +++ b/llvm/lib/Analysis/LazyValueInfo.cpp @@ -19,8 +19,8 @@ #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/TargetLibraryInfo.h" -#include "llvm/Analysis/ValueTracking.h" #include "llvm/Analysis/ValueLattice.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/AssemblyAnnotationWriter.h" #include "llvm/IR/CFG.h" #include "llvm/IR/ConstantRange.h" @@ -33,6 +33,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/PatternMatch.h" #include "llvm/IR/ValueHandle.h" +#include "llvm/InitializePasses.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/raw_ostream.h" @@ -47,6 +48,9 @@ using namespace PatternMatch; static const unsigned MaxProcessedPerValue = 500; char LazyValueInfoWrapperPass::ID = 0; +LazyValueInfoWrapperPass::LazyValueInfoWrapperPass() : FunctionPass(ID) { + initializeLazyValueInfoWrapperPassPass(*PassRegistry::getPassRegistry()); +} INITIALIZE_PASS_BEGIN(LazyValueInfoWrapperPass, "lazy-value-info", "Lazy Value Information Analysis", false, true) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) @@ -432,6 +436,8 @@ namespace { BasicBlock *BB); bool solveBlockValueOverflowIntrinsic( ValueLatticeElement &BBLV, WithOverflowInst *WO, BasicBlock *BB); + bool solveBlockValueSaturatingIntrinsic(ValueLatticeElement &BBLV, + SaturatingInst *SI, BasicBlock *BB); bool solveBlockValueIntrinsic(ValueLatticeElement &BBLV, IntrinsicInst *II, BasicBlock *BB); bool solveBlockValueExtractValue(ValueLatticeElement &BBLV, @@ -1090,8 +1096,22 @@ bool LazyValueInfoImpl::solveBlockValueBinaryOp(ValueLatticeElement &BBLV, return true; } - return solveBlockValueBinaryOpImpl(BBLV, BO, BB, - [BO](const ConstantRange &CR1, const ConstantRange &CR2) { + if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(BO)) { + unsigned NoWrapKind = 0; + if (OBO->hasNoUnsignedWrap()) + NoWrapKind |= OverflowingBinaryOperator::NoUnsignedWrap; + if (OBO->hasNoSignedWrap()) + NoWrapKind |= OverflowingBinaryOperator::NoSignedWrap; + + return solveBlockValueBinaryOpImpl( + BBLV, BO, BB, + [BO, NoWrapKind](const ConstantRange &CR1, const ConstantRange &CR2) { + return CR1.overflowingBinaryOp(BO->getOpcode(), CR2, NoWrapKind); + }); + } + + return solveBlockValueBinaryOpImpl( + BBLV, BO, BB, [BO](const ConstantRange &CR1, const ConstantRange &CR2) { return CR1.binaryOp(BO->getOpcode(), CR2); }); } @@ -1104,37 +1124,46 @@ bool LazyValueInfoImpl::solveBlockValueOverflowIntrinsic( }); } -bool LazyValueInfoImpl::solveBlockValueIntrinsic( - ValueLatticeElement &BBLV, IntrinsicInst *II, BasicBlock *BB) { - switch (II->getIntrinsicID()) { +bool LazyValueInfoImpl::solveBlockValueSaturatingIntrinsic( + ValueLatticeElement &BBLV, SaturatingInst *SI, BasicBlock *BB) { + switch (SI->getIntrinsicID()) { case Intrinsic::uadd_sat: - return solveBlockValueBinaryOpImpl(BBLV, II, BB, - [](const ConstantRange &CR1, const ConstantRange &CR2) { + return solveBlockValueBinaryOpImpl( + BBLV, SI, BB, [](const ConstantRange &CR1, const ConstantRange &CR2) { return CR1.uadd_sat(CR2); }); case Intrinsic::usub_sat: - return solveBlockValueBinaryOpImpl(BBLV, II, BB, - [](const ConstantRange &CR1, const ConstantRange &CR2) { + return solveBlockValueBinaryOpImpl( + BBLV, SI, BB, [](const ConstantRange &CR1, const ConstantRange &CR2) { return CR1.usub_sat(CR2); }); case Intrinsic::sadd_sat: - return solveBlockValueBinaryOpImpl(BBLV, II, BB, - [](const ConstantRange &CR1, const ConstantRange &CR2) { + return solveBlockValueBinaryOpImpl( + BBLV, SI, BB, [](const ConstantRange &CR1, const ConstantRange &CR2) { return CR1.sadd_sat(CR2); }); case Intrinsic::ssub_sat: - return solveBlockValueBinaryOpImpl(BBLV, II, BB, - [](const ConstantRange &CR1, const ConstantRange &CR2) { + return solveBlockValueBinaryOpImpl( + BBLV, SI, BB, [](const ConstantRange &CR1, const ConstantRange &CR2) { return CR1.ssub_sat(CR2); }); default: - LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName() - << "' - overdefined (unknown intrinsic).\n"); - BBLV = ValueLatticeElement::getOverdefined(); - return true; + llvm_unreachable("All llvm.sat intrinsic are handled."); } } +bool LazyValueInfoImpl::solveBlockValueIntrinsic(ValueLatticeElement &BBLV, + IntrinsicInst *II, + BasicBlock *BB) { + if (auto *SI = dyn_cast<SaturatingInst>(II)) + return solveBlockValueSaturatingIntrinsic(BBLV, SI, BB); + + LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName() + << "' - overdefined (unknown intrinsic).\n"); + BBLV = ValueLatticeElement::getOverdefined(); + return true; +} + bool LazyValueInfoImpl::solveBlockValueExtractValue( ValueLatticeElement &BBLV, ExtractValueInst *EVI, BasicBlock *BB) { if (auto *WO = dyn_cast<WithOverflowInst>(EVI->getAggregateOperand())) |