diff options
| author | Sanjay Patel <spatel@rotateright.com> | 2017-01-24 17:03:24 +0000 |
|---|---|---|
| committer | Sanjay Patel <spatel@rotateright.com> | 2017-01-24 17:03:24 +0000 |
| commit | 562272536a018d4115db05fefa31718620071f91 (patch) | |
| tree | 725b90fc3b5281eb7d631ee80083db454c6e863d /llvm/lib/Analysis | |
| parent | 5bdb95c078e66344fd57ff8113c78748fc9eafc0 (diff) | |
| download | bcm5719-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.cpp | 20 |
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: |

