diff options
author | Noah Goldstein <goldstein.w.n@gmail.com> | 2023-10-06 15:18:21 -0500 |
---|---|---|
committer | Noah Goldstein <goldstein.w.n@gmail.com> | 2023-10-12 14:12:26 -0500 |
commit | 0f8b40a82ebeec65eb560d85368b1540333897f8 (patch) | |
tree | e8a33062f1a3f9379d7cb91e4d199f17e2a57475 /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 457308a46a37fd56af06664ad923a06d50243a56 (diff) | |
download | llvm-0f8b40a82ebeec65eb560d85368b1540333897f8.zip llvm-0f8b40a82ebeec65eb560d85368b1540333897f8.tar.gz llvm-0f8b40a82ebeec65eb560d85368b1540333897f8.tar.bz2 |
[ValueTracking] Add better support for ConstantRange(Shl)
1) If LHS is constant:
- The low bits of the LHS is set, the lower bound is non-zero
- The upper bound can be capped at popcount(LHS) high bits
2) If RHS is constant:
- The upper bound can be capped at (Width - RHS) high bits
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index e186431..9b29d64 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8553,7 +8553,20 @@ static void setLimitsForBinOp(const BinaryOperator &BO, APInt &Lower, Lower = *C; Upper = C->shl(ShiftAmount) + 1; } + } else { + // If lowbit is set, value can never be zero. + if ((*C)[0]) + Lower = APInt::getOneBitSet(Width, 0); + // If we are shifting a constant the largest it can be is if the longest + // sequence of consecutive ones is shifted to the highbits (breaking + // ties for which sequence is higher). At the moment we take a liberal + // upper bound on this by just popcounting the constant. + // TODO: There may be a bitwise trick for it longest/highest + // consecutative sequence of ones (naive method is O(Width) loop). + Upper = APInt::getHighBitsSet(Width, C->popcount()) + 1; } + } else if (match(BO.getOperand(1), m_APInt(C)) && C->ult(Width)) { + Upper = APInt::getBitsSetFrom(Width, C->getZExtValue()) + 1; } break; |