summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-05-28 18:08:31 +0000
committerNikita Popov <nikita.ppv@gmail.com>2019-05-28 18:08:31 +0000
commit332c10056227d5da5557f50e8c64dc8814ca56f0 (patch)
tree4ca1abc675a10809ee43eefec87544139d77c3ef /llvm/lib
parent2fb0a820df9c9884b9f42efdd0919b309e2b1204 (diff)
downloadbcm5719-llvm-332c10056227d5da5557f50e8c64dc8814ca56f0.tar.gz
bcm5719-llvm-332c10056227d5da5557f50e8c64dc8814ca56f0.zip
[ValueTracking][ConstantRange] Distinguish low/high always overflow
In order to fold an always overflowing signed saturating add/sub, we need to know in which direction the always overflow occurs. This patch splits up AlwaysOverflows into AlwaysOverflowsLow and AlwaysOverflowsHigh to pass through this information (but it is not used yet). Differential Revision: https://reviews.llvm.org/D62463 llvm-svn: 361858
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp6
-rw-r--r--llvm/lib/IR/ConstantRange.cpp18
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp4
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp3
4 files changed, 17 insertions, 14 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index d46ddc428b2..640063700e8 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3992,8 +3992,10 @@ static OverflowResult mapOverflowResult(ConstantRange::OverflowResult OR) {
switch (OR) {
case ConstantRange::OverflowResult::MayOverflow:
return OverflowResult::MayOverflow;
- case ConstantRange::OverflowResult::AlwaysOverflows:
- return OverflowResult::AlwaysOverflows;
+ case ConstantRange::OverflowResult::AlwaysOverflowsLow:
+ return OverflowResult::AlwaysOverflowsLow;
+ case ConstantRange::OverflowResult::AlwaysOverflowsHigh:
+ return OverflowResult::AlwaysOverflowsHigh;
case ConstantRange::OverflowResult::NeverOverflows:
return OverflowResult::NeverOverflows;
}
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp
index 0d44c3815b3..30b6a27078c 100644
--- a/llvm/lib/IR/ConstantRange.cpp
+++ b/llvm/lib/IR/ConstantRange.cpp
@@ -1208,9 +1208,9 @@ ConstantRange::OverflowResult ConstantRange::unsignedAddMayOverflow(
APInt Min = getUnsignedMin(), Max = getUnsignedMax();
APInt OtherMin = Other.getUnsignedMin(), OtherMax = Other.getUnsignedMax();
- // a u+ b overflows iff a u> ~b.
+ // a u+ b overflows high iff a u> ~b.
if (Min.ugt(~OtherMin))
- return OverflowResult::AlwaysOverflows;
+ return OverflowResult::AlwaysOverflowsHigh;
if (Max.ugt(~OtherMax))
return OverflowResult::MayOverflow;
return OverflowResult::NeverOverflows;
@@ -1231,10 +1231,10 @@ ConstantRange::OverflowResult ConstantRange::signedAddMayOverflow(
// a s+ b overflows low iff a s< 0 && b s< 0 && a s< smin - b.
if (Min.isNonNegative() && OtherMin.isNonNegative() &&
Min.sgt(SignedMax - OtherMin))
- return OverflowResult::AlwaysOverflows;
+ return OverflowResult::AlwaysOverflowsHigh;
if (Max.isNegative() && OtherMax.isNegative() &&
Max.slt(SignedMin - OtherMax))
- return OverflowResult::AlwaysOverflows;
+ return OverflowResult::AlwaysOverflowsLow;
if (Max.isNonNegative() && OtherMax.isNonNegative() &&
Max.sgt(SignedMax - OtherMax))
@@ -1254,9 +1254,9 @@ ConstantRange::OverflowResult ConstantRange::unsignedSubMayOverflow(
APInt Min = getUnsignedMin(), Max = getUnsignedMax();
APInt OtherMin = Other.getUnsignedMin(), OtherMax = Other.getUnsignedMax();
- // a u- b overflows iff a u< b.
+ // a u- b overflows low iff a u< b.
if (Max.ult(OtherMin))
- return OverflowResult::AlwaysOverflows;
+ return OverflowResult::AlwaysOverflowsLow;
if (Min.ult(OtherMax))
return OverflowResult::MayOverflow;
return OverflowResult::NeverOverflows;
@@ -1277,10 +1277,10 @@ ConstantRange::OverflowResult ConstantRange::signedSubMayOverflow(
// a s- b overflows low iff a s< 0 && b s>= 0 && a s< smin + b.
if (Min.isNonNegative() && OtherMax.isNegative() &&
Min.sgt(SignedMax + OtherMax))
- return OverflowResult::AlwaysOverflows;
+ return OverflowResult::AlwaysOverflowsHigh;
if (Max.isNegative() && OtherMin.isNonNegative() &&
Max.slt(SignedMin + OtherMin))
- return OverflowResult::AlwaysOverflows;
+ return OverflowResult::AlwaysOverflowsLow;
if (Max.isNonNegative() && OtherMin.isNegative() &&
Max.sgt(SignedMax + OtherMin))
@@ -1303,7 +1303,7 @@ ConstantRange::OverflowResult ConstantRange::unsignedMulMayOverflow(
(void) Min.umul_ov(OtherMin, Overflow);
if (Overflow)
- return OverflowResult::AlwaysOverflows;
+ return OverflowResult::AlwaysOverflowsHigh;
(void) Max.umul_ov(OtherMax, Overflow);
if (Overflow)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index e2813f9d9d4..a18043ef33f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2064,7 +2064,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
OR = computeOverflowForUnsignedAdd(Arg0, Arg1, II);
if (OR == OverflowResult::NeverOverflows)
return BinaryOperator::CreateNUWAdd(Arg0, Arg1);
- if (OR == OverflowResult::AlwaysOverflows)
+ if (OR == OverflowResult::AlwaysOverflowsHigh)
return replaceInstUsesWith(*II,
ConstantInt::getAllOnesValue(II->getType()));
break;
@@ -2072,7 +2072,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
OR = computeOverflowForUnsignedSub(Arg0, Arg1, II);
if (OR == OverflowResult::NeverOverflows)
return BinaryOperator::CreateNUWSub(Arg0, Arg1);
- if (OR == OverflowResult::AlwaysOverflows)
+ if (OR == OverflowResult::AlwaysOverflowsLow)
return replaceInstUsesWith(*II,
ConstantInt::getNullValue(II->getType()));
break;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index ab2da177d7b..b3eb75ea8a8 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3993,7 +3993,8 @@ bool InstCombiner::OptimizeOverflowCheck(
switch (computeOverflow(BinaryOp, IsSigned, LHS, RHS, &OrigI)) {
case OverflowResult::MayOverflow:
return false;
- case OverflowResult::AlwaysOverflows:
+ case OverflowResult::AlwaysOverflowsLow:
+ case OverflowResult::AlwaysOverflowsHigh:
Result = Builder.CreateBinOp(BinaryOp, LHS, RHS);
Result->takeName(&OrigI);
Overflow = Builder.getTrue();
OpenPOWER on IntegriCloud