aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
diff options
context:
space:
mode:
authorMax Kazantsev <max.kazantsev@azul.com>2018-10-11 07:22:26 +0000
committerMax Kazantsev <max.kazantsev@azul.com>2018-10-11 07:22:26 +0000
commitb2e51090a427be5a804af53ac3615672ae356074 (patch)
tree669d7ca7f776410d0a7128f5e310404cbad07ff0 /llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
parent523904133894888592a280ff7d0f0579418901f9 (diff)
downloadllvm-b2e51090a427be5a804af53ac3615672ae356074.zip
llvm-b2e51090a427be5a804af53ac3615672ae356074.tar.gz
llvm-b2e51090a427be5a804af53ac3615672ae356074.tar.bz2
[IndVars] Drop "exact" flag from lshr and udiv when substituting their args
There is a transform that may replace `lshr (x+1), 1` with `lshr x, 1` in case if it can prove that the result will be the same. However the initial instruction might have an `exact` flag set, and it now should be dropped unless we prove that it may hold. Incorrectly set `exact` attribute may then produce poison. Differential Revision: https://reviews.llvm.org/D53061 Reviewed By: sanjoy llvm-svn: 344223
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyIndVar.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyIndVar.cpp9
1 files changed, 9 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index 51fda1c..7faf291 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -108,6 +108,7 @@ Value *SimplifyIndvar::foldIVUser(Instruction *UseInst, Instruction *IVOperand)
Value *IVSrc = nullptr;
const unsigned OperIdx = 0;
const SCEV *FoldedExpr = nullptr;
+ bool MustDropExactFlag = false;
switch (UseInst->getOpcode()) {
default:
return nullptr;
@@ -140,6 +141,11 @@ Value *SimplifyIndvar::foldIVUser(Instruction *UseInst, Instruction *IVOperand)
APInt::getOneBitSet(BitWidth, D->getZExtValue()));
}
FoldedExpr = SE->getUDivExpr(SE->getSCEV(IVSrc), SE->getSCEV(D));
+ // We might have 'exact' flag set at this point which will no longer be
+ // correct after we make the replacement.
+ if (UseInst->isExact() &&
+ SE->getSCEV(IVSrc) != SE->getMulExpr(FoldedExpr, SE->getSCEV(D)))
+ MustDropExactFlag = true;
}
// We have something that might fold it's operand. Compare SCEVs.
if (!SE->isSCEVable(UseInst->getType()))
@@ -155,6 +161,9 @@ Value *SimplifyIndvar::foldIVUser(Instruction *UseInst, Instruction *IVOperand)
UseInst->setOperand(OperIdx, IVSrc);
assert(SE->getSCEV(UseInst) == FoldedExpr && "bad SCEV with folded oper");
+ if (MustDropExactFlag)
+ UseInst->dropPoisonGeneratingFlags();
+
++NumElimOperand;
Changed = true;
if (IVOperand->use_empty())