summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-05-31 20:48:26 +0000
committerNikita Popov <nikita.ppv@gmail.com>2019-05-31 20:48:26 +0000
commit7bafae55c01dda8478aeff74a8d657a4148630af (patch)
tree7c0b11691f9dbb847ce733ffd832d212973cca32 /llvm/lib
parentd43509305674e89e6ac482b5a76c2ac20c2de1c4 (diff)
downloadbcm5719-llvm-7bafae55c01dda8478aeff74a8d657a4148630af.tar.gz
bcm5719-llvm-7bafae55c01dda8478aeff74a8d657a4148630af.zip
Reapply [CVP] Simplify non-overflowing saturating add/sub
If we can determine that a saturating add/sub will not overflow based on range analysis, convert it into a simple binary operation. This is a sibling transform to the existing with.overflow handling. Reapplying this with an additional check that the saturating intrinsic has integer type, as LVI currently does not support vector types. Differential Revision: https://reviews.llvm.org/D62703 llvm-svn: 362263
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp25
1 files changed, 24 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index 9ec2afb99d6..5bfdf17c9a0 100644
--- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -63,6 +63,8 @@ STATISTIC(NumUDivs, "Number of udivs whose width was decreased");
STATISTIC(NumAShrs, "Number of ashr converted to lshr");
STATISTIC(NumSRems, "Number of srem converted to urem");
STATISTIC(NumOverflows, "Number of overflow checks removed");
+STATISTIC(NumSaturating,
+ "Number of saturating arithmetics converted to normal arithmetics");
static cl::opt<bool> DontAddNoWrapFlags("cvp-dont-add-nowrap-flags", cl::init(true));
@@ -413,7 +415,7 @@ static void processOverflowIntrinsic(WithOverflowInst *WO) {
IRBuilder<> B(WO);
Value *NewOp = B.CreateBinOp(
WO->getBinaryOp(), WO->getLHS(), WO->getRHS(), WO->getName());
- // Constant-holing could have happened.
+ // Constant-folding could have happened.
if (auto *Inst = dyn_cast<Instruction>(NewOp)) {
if (WO->isSigned())
Inst->setHasNoSignedWrap();
@@ -428,6 +430,20 @@ static void processOverflowIntrinsic(WithOverflowInst *WO) {
++NumOverflows;
}
+static void processSaturatingInst(SaturatingInst *SI) {
+ BinaryOperator *BinOp = BinaryOperator::Create(
+ SI->getBinaryOp(), SI->getLHS(), SI->getRHS(), SI->getName(), SI);
+ BinOp->setDebugLoc(SI->getDebugLoc());
+ if (SI->isSigned())
+ BinOp->setHasNoSignedWrap();
+ else
+ BinOp->setHasNoUnsignedWrap();
+
+ SI->replaceAllUsesWith(BinOp);
+ SI->eraseFromParent();
+ ++NumSaturating;
+}
+
/// Infer nonnull attributes for the arguments at the specified callsite.
static bool processCallSite(CallSite CS, LazyValueInfo *LVI) {
SmallVector<unsigned, 4> ArgNos;
@@ -440,6 +456,13 @@ static bool processCallSite(CallSite CS, LazyValueInfo *LVI) {
}
}
+ if (auto *SI = dyn_cast<SaturatingInst>(CS.getInstruction())) {
+ if (SI->getType()->isIntegerTy() && willNotOverflow(SI, LVI)) {
+ processSaturatingInst(SI);
+ return true;
+ }
+ }
+
// Deopt bundle operands are intended to capture state with minimal
// perturbance of the code otherwise. If we can find a constant value for
// any such operand and remove a use of the original value, that's
OpenPOWER on IntegriCloud