summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2017-01-24 17:03:24 +0000
committerSanjay Patel <spatel@rotateright.com>2017-01-24 17:03:24 +0000
commit562272536a018d4115db05fefa31718620071f91 (patch)
tree725b90fc3b5281eb7d631ee80083db454c6e863d /llvm/lib/Analysis
parent5bdb95c078e66344fd57ff8113c78748fc9eafc0 (diff)
downloadbcm5719-llvm-562272536a018d4115db05fefa31718620071f91.tar.gz
bcm5719-llvm-562272536a018d4115db05fefa31718620071f91.zip
[InstSimplify] try to eliminate icmp Pred (add nsw X, C1), C2
I was surprised to see that we're missing icmp folds based on 'add nsw' in InstCombine, but we should handle the InstSimplify cases first because that could make the InstCombine code simpler. Here are Alive-based proofs for the logic: Name: add_neg_constant Pre: C1 < 0 && (C2 > ((1<<(width(C1)-1)) + C1)) %a = add nsw i7 %x, C1 %b = icmp sgt %a, C2 => %b = false Name: add_pos_constant Pre: C1 > 0 && (C2 < ((1<<(width(C1)-1)) + C1 - 1)) %a = add nsw i6 %x, C1 %b = icmp slt %a, C2 => %b = false Name: nuw Pre: C1 u>= C2 %a = add nuw i11 %x, C1 %b = icmp ult %a, C2 => %b = false Differential Revision: https://reviews.llvm.org/D29053 llvm-svn: 292952
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/InstructionSimplify.cpp20
1 files changed, 17 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 5245b4914de..fc0b86aaa39 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2385,9 +2385,23 @@ static void setLimitsForBinOp(BinaryOperator &BO, APInt &Lower, APInt &Upper) {
const APInt *C;
switch (BO.getOpcode()) {
case Instruction::Add:
- if (BO.hasNoUnsignedWrap() && match(BO.getOperand(1), m_APInt(C)))
- // 'add nuw x, C' produces [C, UINT_MAX].
- Lower = *C;
+ if (match(BO.getOperand(1), m_APInt(C)) && *C != 0) {
+ // FIXME: If we have both nuw and nsw, we should reduce the range further.
+ if (BO.hasNoUnsignedWrap()) {
+ // 'add nuw x, C' produces [C, UINT_MAX].
+ Lower = *C;
+ } else if (BO.hasNoSignedWrap()) {
+ if (C->isNegative()) {
+ // 'add nsw x, -C' produces [SINT_MIN, SINT_MAX - C].
+ Lower = APInt::getSignedMinValue(Width);
+ Upper = APInt::getSignedMaxValue(Width) + *C + 1;
+ } else {
+ // 'add nsw x, +C' produces [SINT_MIN + C, SINT_MAX].
+ Lower = APInt::getSignedMinValue(Width) + *C;
+ Upper = APInt::getSignedMaxValue(Width) + 1;
+ }
+ }
+ }
break;
case Instruction::And:
OpenPOWER on IntegriCloud