summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp54
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp61
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyIndVar.cpp107
3 files changed, 5 insertions, 217 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 6366e3621ae..654a766b416 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -3831,7 +3831,7 @@ struct BinaryOp {
/// Try to map \p V into a BinaryOp, and return \c None on failure.
-static Optional<BinaryOp> MatchBinaryOp(Value *V, DominatorTree &DT) {
+static Optional<BinaryOp> MatchBinaryOp(Value *V) {
auto *Op = dyn_cast<Operator>(V);
if (!Op)
return None;
@@ -3877,50 +3877,6 @@ static Optional<BinaryOp> MatchBinaryOp(Value *V, DominatorTree &DT) {
}
return BinaryOp(Op);
- case Instruction::ExtractValue: {
- auto *EVI = cast<ExtractValueInst>(Op);
- if (EVI->getNumIndices() != 1 || EVI->getIndices()[0] != 0)
- break;
-
- auto *CI = dyn_cast<CallInst>(EVI->getAggregateOperand());
- if (!CI)
- break;
-
- if (auto *F = CI->getCalledFunction())
- switch (F->getIntrinsicID()) {
- case Intrinsic::sadd_with_overflow:
- case Intrinsic::uadd_with_overflow: {
- if (!isOverflowIntrinsicNoWrap(cast<IntrinsicInst>(CI), DT))
- return BinaryOp(Instruction::Add, CI->getArgOperand(0),
- CI->getArgOperand(1));
-
- // Now that we know that all uses of the arithmetic-result component of
- // CI are guarded by the overflow check, we can go ahead and pretend
- // that the arithmetic is non-overflowing.
- if (F->getIntrinsicID() == Intrinsic::sadd_with_overflow)
- return BinaryOp(Instruction::Add, CI->getArgOperand(0),
- CI->getArgOperand(1), /* IsNSW = */ true,
- /* IsNUW = */ false);
- else
- return BinaryOp(Instruction::Add, CI->getArgOperand(0),
- CI->getArgOperand(1), /* IsNSW = */ false,
- /* IsNUW*/ true);
- }
-
- case Intrinsic::ssub_with_overflow:
- case Intrinsic::usub_with_overflow:
- return BinaryOp(Instruction::Sub, CI->getArgOperand(0),
- CI->getArgOperand(1));
-
- case Intrinsic::smul_with_overflow:
- case Intrinsic::umul_with_overflow:
- return BinaryOp(Instruction::Mul, CI->getArgOperand(0),
- CI->getArgOperand(1));
- default:
- break;
- }
- }
-
default:
break;
}
@@ -3997,7 +3953,7 @@ const SCEV *ScalarEvolution::createAddRecFromPHI(PHINode *PN) {
// If the increment doesn't overflow, then neither the addrec nor
// the post-increment will overflow.
- if (auto BO = MatchBinaryOp(BEValueV, DT)) {
+ if (auto BO = MatchBinaryOp(BEValueV)) {
if (BO->Opcode == Instruction::Add && BO->LHS == PN) {
if (BO->IsNUW)
Flags = setFlags(Flags, SCEV::FlagNUW);
@@ -4877,7 +4833,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
return getUnknown(V);
Operator *U = cast<Operator>(V);
- if (auto BO = MatchBinaryOp(U, DT)) {
+ if (auto BO = MatchBinaryOp(U)) {
switch (BO->Opcode) {
case Instruction::Add: {
// The simple thing to do would be to just call getSCEV on both operands
@@ -4918,7 +4874,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
else
AddOps.push_back(getSCEV(BO->RHS));
- auto NewBO = MatchBinaryOp(BO->LHS, DT);
+ auto NewBO = MatchBinaryOp(BO->LHS);
if (!NewBO || (NewBO->Opcode != Instruction::Add &&
NewBO->Opcode != Instruction::Sub)) {
AddOps.push_back(getSCEV(BO->LHS));
@@ -4948,7 +4904,7 @@ const SCEV *ScalarEvolution::createSCEV(Value *V) {
}
MulOps.push_back(getSCEV(BO->RHS));
- auto NewBO = MatchBinaryOp(BO->LHS, DT);
+ auto NewBO = MatchBinaryOp(BO->LHS);
if (!NewBO || NewBO->Opcode != Instruction::Mul) {
MulOps.push_back(getSCEV(BO->LHS));
break;
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 6df22943ce1..6f8dc2c2937 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3253,67 +3253,6 @@ static OverflowResult computeOverflowForSignedAdd(
return OverflowResult::MayOverflow;
}
-bool llvm::isOverflowIntrinsicNoWrap(IntrinsicInst *II, DominatorTree &DT) {
-#ifndef NDEBUG
- auto IID = II->getIntrinsicID();
- assert((IID == Intrinsic::sadd_with_overflow ||
- IID == Intrinsic::uadd_with_overflow ||
- IID == Intrinsic::ssub_with_overflow ||
- IID == Intrinsic::usub_with_overflow ||
- IID == Intrinsic::smul_with_overflow ||
- IID == Intrinsic::umul_with_overflow) &&
- "Not an overflow intrinsic!");
-#endif
-
- SmallVector<BranchInst *, 2> GuardingBranches;
- SmallVector<ExtractValueInst *, 2> Results;
-
- for (User *U : II->users()) {
- if (auto *EVI = dyn_cast<ExtractValueInst>(U)) {
- assert(EVI->getNumIndices() == 1 && "Obvious from CI's type");
-
- if (EVI->getIndices()[0] == 0)
- Results.push_back(EVI);
- else {
- assert(EVI->getIndices()[0] == 1 && "Obvious from CI's type");
-
- for (auto *U : EVI->users())
- if (auto *B = dyn_cast<BranchInst>(U)) {
- assert(B->isConditional() && "How else is it using an i1?");
- GuardingBranches.push_back(B);
- }
- }
- } else {
- // We are using the aggregate directly in a way we don't want to analyze
- // here (storing it to a global, say).
- return false;
- }
- }
-
- auto AllUsesGuardedByBranch = [&](BranchInst *BI) {
- BasicBlockEdge NoWrapEdge(BI->getParent(), BI->getSuccessor(1));
- if (!NoWrapEdge.isSingleEdge())
- return false;
-
- // Check if all users of the add are provably no-wrap.
- for (auto *Result : Results) {
- // If the extractvalue itself is not executed on overflow, the we don't
- // need to check each use separately, since domination is transitive.
- if (DT.dominates(NoWrapEdge, Result->getParent()))
- continue;
-
- for (auto &RU : Result->uses())
- if (!DT.dominates(NoWrapEdge, RU))
- return false;
- }
-
- return true;
- };
-
- return any_of(GuardingBranches, AllUsesGuardedByBranch);
-}
-
-
OverflowResult llvm::computeOverflowForSignedAdd(AddOperator *Add,
const DataLayout &DL,
AssumptionCache *AC,
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index e542d403c7e..c95f10e1b7b 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -71,7 +71,6 @@ namespace {
bool eliminateIdentitySCEV(Instruction *UseInst, Instruction *IVOperand);
- bool eliminateOverflowIntrinsic(CallInst *CI);
bool eliminateIVUser(Instruction *UseInst, Instruction *IVOperand);
void eliminateIVComparison(ICmpInst *ICmp, Value *IVOperand);
void eliminateIVRemainder(BinaryOperator *Rem, Value *IVOperand,
@@ -319,108 +318,6 @@ void SimplifyIndvar::eliminateIVRemainder(BinaryOperator *Rem,
DeadInsts.emplace_back(Rem);
}
-bool SimplifyIndvar::eliminateOverflowIntrinsic(CallInst *CI) {
- auto *F = CI->getCalledFunction();
- if (!F)
- return false;
-
- typedef const SCEV *(ScalarEvolution::*OperationFunctionTy)(
- const SCEV *, const SCEV *, SCEV::NoWrapFlags);
- typedef const SCEV *(ScalarEvolution::*ExtensionFunctionTy)(
- const SCEV *, Type *);
-
- OperationFunctionTy Operation;
- ExtensionFunctionTy Extension;
-
- Instruction::BinaryOps RawOp;
-
- // We always have exactly one of nsw or nuw. If NoSignedOverflow is false, we
- // have nuw.
- bool NoSignedOverflow;
-
- switch (F->getIntrinsicID()) {
- default:
- return false;
-
- case Intrinsic::sadd_with_overflow:
- Operation = &ScalarEvolution::getAddExpr;
- Extension = &ScalarEvolution::getSignExtendExpr;
- RawOp = Instruction::Add;
- NoSignedOverflow = true;
- break;
-
- case Intrinsic::uadd_with_overflow:
- Operation = &ScalarEvolution::getAddExpr;
- Extension = &ScalarEvolution::getZeroExtendExpr;
- RawOp = Instruction::Add;
- NoSignedOverflow = false;
- break;
-
- case Intrinsic::ssub_with_overflow:
- Operation = &ScalarEvolution::getMinusSCEV;
- Extension = &ScalarEvolution::getSignExtendExpr;
- RawOp = Instruction::Sub;
- NoSignedOverflow = true;
- break;
-
- case Intrinsic::usub_with_overflow:
- Operation = &ScalarEvolution::getMinusSCEV;
- Extension = &ScalarEvolution::getZeroExtendExpr;
- RawOp = Instruction::Sub;
- NoSignedOverflow = false;
- break;
- }
-
- const SCEV *LHS = SE->getSCEV(CI->getArgOperand(0));
- const SCEV *RHS = SE->getSCEV(CI->getArgOperand(1));
-
- auto *NarrowTy = cast<IntegerType>(LHS->getType());
- auto *WideTy =
- IntegerType::get(NarrowTy->getContext(), NarrowTy->getBitWidth() * 2);
-
- const SCEV *A =
- (SE->*Extension)((SE->*Operation)(LHS, RHS, SCEV::FlagAnyWrap), WideTy);
- const SCEV *B =
- (SE->*Operation)((SE->*Extension)(LHS, WideTy),
- (SE->*Extension)(RHS, WideTy), SCEV::FlagAnyWrap);
-
- if (A != B)
- return false;
-
- // Proved no overflow, nuke the overflow check and, if possible, the overflow
- // intrinsic as well.
-
- BinaryOperator *NewResult = BinaryOperator::Create(
- RawOp, CI->getArgOperand(0), CI->getArgOperand(1), "", CI);
-
- if (NoSignedOverflow)
- NewResult->setHasNoSignedWrap(true);
- else
- NewResult->setHasNoUnsignedWrap(true);
-
- SmallVector<ExtractValueInst *, 4> ToDelete;
-
- for (auto *U : CI->users()) {
- if (auto *EVI = dyn_cast<ExtractValueInst>(U)) {
- if (EVI->getIndices()[0] == 1)
- EVI->replaceAllUsesWith(ConstantInt::getFalse(CI->getContext()));
- else {
- assert(EVI->getIndices()[0] == 0 && "Only two possibilities!");
- EVI->replaceAllUsesWith(NewResult);
- }
- ToDelete.push_back(EVI);
- }
- }
-
- for (auto *EVI : ToDelete)
- EVI->eraseFromParent();
-
- if (CI->use_empty())
- CI->eraseFromParent();
-
- return true;
-}
-
/// Eliminate an operation that consumes a simple IV and has no observable
/// side-effect given the range of IV values. IVOperand is guaranteed SCEVable,
/// but UseInst may not be.
@@ -438,10 +335,6 @@ bool SimplifyIndvar::eliminateIVUser(Instruction *UseInst,
}
}
- if (auto *CI = dyn_cast<CallInst>(UseInst))
- if (eliminateOverflowIntrinsic(CI))
- return true;
-
if (eliminateIdentitySCEV(UseInst, IVOperand))
return true;
OpenPOWER on IntegriCloud