summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorArtur Pilipenko <apilipenko@azulsystems.com>2016-08-10 13:08:34 +0000
committerArtur Pilipenko <apilipenko@azulsystems.com>2016-08-10 13:08:34 +0000
commite171ea8a33198c3b257c110a5fecc97acdbb5b52 (patch)
treed10fcd7614d9ed04a7270751c5feb03e83b16ef9 /llvm/lib/Transforms
parentdfc1b900aca0fd4aa4b8ccf45f407ea96c5bdaff (diff)
downloadbcm5719-llvm-e171ea8a33198c3b257c110a5fecc97acdbb5b52.tar.gz
bcm5719-llvm-e171ea8a33198c3b257c110a5fecc97acdbb5b52.zip
Teach CorrelatedValuePropagation to mark adds as no wrap
This is a resubmission of previously reverted r277592. It was hitting overly strong assertion in getConstantRange which was relaxed in r278217. Use LVI to prove that adds do not wrap. The change is motivated by https://llvm.org/bugs/show_bug.cgi?id=28620 bug and it's the first step to fix that problem. Reviewed By: sanjoy Differential Revision: http://reviews.llvm.org/D23059 llvm-svn: 278220
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp57
1 files changed, 57 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index c0fed053339..8b0d7e4d19a 100644
--- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
+++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
@@ -18,6 +18,7 @@
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LazyValueInfo.h"
#include "llvm/IR/CFG.h"
+#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
@@ -381,6 +382,59 @@ static bool processSDiv(BinaryOperator *SDI, LazyValueInfo *LVI) {
return true;
}
+static bool processAdd(BinaryOperator *AddOp, LazyValueInfo *LVI) {
+ typedef OverflowingBinaryOperator OBO;
+
+ 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;
+}
+
static Constant *getConstantAt(Value *V, Instruction *At, LazyValueInfo *LVI) {
if (Constant *C = LVI->getConstant(V, At->getParent(), At))
return C;
@@ -436,6 +490,9 @@ static bool runImpl(Function &F, LazyValueInfo *LVI) {
case Instruction::SDiv:
BBChanged |= processSDiv(cast<BinaryOperator>(II), LVI);
break;
+ case Instruction::Add:
+ BBChanged |= processAdd(cast<BinaryOperator>(II), LVI);
+ break;
}
}
OpenPOWER on IntegriCloud