summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-01-07 00:39:50 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-01-07 00:39:50 +0000
commit5310c1e9549c18af257eaf2c13782e29419dc28d (patch)
tree30e42c993321fa68401184e7a509272e2932cb67 /llvm/lib/Transforms
parent3b83b3fa0bc874a6b02c97e026ddc3bfa9f0bdd4 (diff)
downloadbcm5719-llvm-5310c1e9549c18af257eaf2c13782e29419dc28d.tar.gz
bcm5719-llvm-5310c1e9549c18af257eaf2c13782e29419dc28d.zip
Analysis: Reformulate WillNotOverflowUnsignedAdd for reusability
WillNotOverflowUnsignedAdd's smarts will live in ValueTracking as computeOverflowForUnsignedAdd. It now returns a tri-state result: never overflows, always overflows and sometimes overflows. llvm-svn: 225329
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombine.h5
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp20
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp32
3 files changed, 12 insertions, 45 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombine.h b/llvm/lib/Transforms/InstCombine/InstCombine.h
index 4c8e8d4e59c..3c3c1355193 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombine.h
+++ b/llvm/lib/Transforms/InstCombine/InstCombine.h
@@ -282,7 +282,6 @@ private:
bool DoXform = true);
Instruction *transformSExtICmp(ICmpInst *ICI, Instruction &CI);
bool WillNotOverflowSignedAdd(Value *LHS, Value *RHS, Instruction *CxtI);
- bool WillNotOverflowUnsignedAdd(Value *LHS, Value *RHS, Instruction *CxtI);
bool WillNotOverflowSignedSub(Value *LHS, Value *RHS, Instruction *CxtI);
bool WillNotOverflowUnsignedSub(Value *LHS, Value *RHS, Instruction *CxtI);
bool WillNotOverflowSignedMul(Value *LHS, Value *RHS, Instruction *CxtI);
@@ -391,6 +390,10 @@ public:
const Instruction *CxtI) {
return llvm::computeOverflowForUnsignedMul(LHS, RHS, DL, AC, CxtI, DT);
}
+ OverflowResult computeOverflowForUnsignedAdd(Value *LHS, Value *RHS,
+ const Instruction *CxtI) {
+ return llvm::computeOverflowForUnsignedAdd(LHS, RHS, DL, AC, CxtI, DT);
+ }
private:
/// SimplifyAssociativeOrCommutative - This performs a few simplifications for
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index fbec98dbec8..6d20384e5d1 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -937,22 +937,6 @@ bool InstCombiner::WillNotOverflowSignedAdd(Value *LHS, Value *RHS,
return false;
}
-/// WillNotOverflowUnsignedAdd - Return true if we can prove that:
-/// (zext (add LHS, RHS)) === (add (zext LHS), (zext RHS))
-bool InstCombiner::WillNotOverflowUnsignedAdd(Value *LHS, Value *RHS,
- Instruction *CxtI) {
- // There are different heuristics we can use for this. Here is a simple one.
- // If the sign bit of LHS and that of RHS are both zero, no unsigned wrap.
- bool LHSKnownNonNegative, LHSKnownNegative;
- bool RHSKnownNonNegative, RHSKnownNegative;
- ComputeSignBit(LHS, LHSKnownNonNegative, LHSKnownNegative, /*Depth=*/0, CxtI);
- ComputeSignBit(RHS, RHSKnownNonNegative, RHSKnownNegative, /*Depth=*/0, CxtI);
- if (LHSKnownNonNegative && RHSKnownNonNegative)
- return true;
-
- return false;
-}
-
/// \brief Return true if we can prove that:
/// (sub LHS, RHS) === (sub nsw LHS, RHS)
/// This basically requires proving that the add in the original type would not
@@ -1327,7 +1311,9 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
Changed = true;
I.setHasNoSignedWrap(true);
}
- if (!I.hasNoUnsignedWrap() && WillNotOverflowUnsignedAdd(LHS, RHS, &I)) {
+ if (!I.hasNoUnsignedWrap() &&
+ computeOverflowForUnsignedAdd(LHS, RHS, &I) ==
+ OverflowResult::NeverOverflows) {
Changed = true;
I.setHasNoUnsignedWrap(true);
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index c42202a2fa6..dab2c4b47ad 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -352,33 +352,11 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
break;
case Intrinsic::uadd_with_overflow: {
Value *LHS = II->getArgOperand(0), *RHS = II->getArgOperand(1);
- IntegerType *IT = cast<IntegerType>(II->getArgOperand(0)->getType());
- uint32_t BitWidth = IT->getBitWidth();
- APInt LHSKnownZero(BitWidth, 0);
- APInt LHSKnownOne(BitWidth, 0);
- computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, 0, II);
- bool LHSKnownNegative = LHSKnownOne[BitWidth - 1];
- bool LHSKnownPositive = LHSKnownZero[BitWidth - 1];
-
- if (LHSKnownNegative || LHSKnownPositive) {
- APInt RHSKnownZero(BitWidth, 0);
- APInt RHSKnownOne(BitWidth, 0);
- computeKnownBits(RHS, RHSKnownZero, RHSKnownOne, 0, II);
- bool RHSKnownNegative = RHSKnownOne[BitWidth - 1];
- bool RHSKnownPositive = RHSKnownZero[BitWidth - 1];
- if (LHSKnownNegative && RHSKnownNegative) {
- // The sign bit is set in both cases: this MUST overflow.
- // Create a simple add instruction, and insert it into the struct.
- return CreateOverflowTuple(II, Builder->CreateAdd(LHS, RHS), true,
- /*ReUseName*/true);
- }
-
- if (LHSKnownPositive && RHSKnownPositive) {
- // The sign bit is clear in both cases: this CANNOT overflow.
- // Create a simple add instruction, and insert it into the struct.
- return CreateOverflowTuple(II, Builder->CreateNUWAdd(LHS, RHS), false);
- }
- }
+ OverflowResult OR = computeOverflowForUnsignedAdd(LHS, RHS, II);
+ if (OR == OverflowResult::NeverOverflows)
+ return CreateOverflowTuple(II, Builder->CreateNUWAdd(LHS, RHS), false);
+ if (OR == OverflowResult::AlwaysOverflows)
+ return CreateOverflowTuple(II, Builder->CreateAdd(LHS, RHS), true);
}
// FALL THROUGH uadd into sadd
case Intrinsic::sadd_with_overflow:
OpenPOWER on IntegriCloud