aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/KnownBits.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2023-05-16 10:55:44 +0200
committerNikita Popov <npopov@redhat.com>2023-06-01 09:46:16 +0200
commitdfb369399d2a54c8dd8752c47ecbf7a8c3c11421 (patch)
treecc57457a7c2fef38895c4363bf46376c117c8dac /llvm/lib/Support/KnownBits.cpp
parent34cf67aef5a3655b57e52842a1bb4913295076e4 (diff)
downloadllvm-dfb369399d2a54c8dd8752c47ecbf7a8c3c11421.zip
llvm-dfb369399d2a54c8dd8752c47ecbf7a8c3c11421.tar.gz
llvm-dfb369399d2a54c8dd8752c47ecbf7a8c3c11421.tar.bz2
[ValueTracking] Directly use KnownBits shift functions
Make ValueTracking directly call the KnownBits shift helpers, which provides more precise results. Unfortunately, ValueTracking has a special case where sometimes we determine non-zero shift amounts using isKnownNonZero(). I have my doubts about the usefulness of that special-case (it is only tested in a single unit test), but I've reproduced the special-case via an extra parameter to the KnownBits methods. Differential Revision: https://reviews.llvm.org/D151816
Diffstat (limited to 'llvm/lib/Support/KnownBits.cpp')
-rw-r--r--llvm/lib/Support/KnownBits.cpp14
1 files changed, 11 insertions, 3 deletions
diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp
index a7ca7c0..84e23d4 100644
--- a/llvm/lib/Support/KnownBits.cpp
+++ b/llvm/lib/Support/KnownBits.cpp
@@ -172,7 +172,7 @@ static unsigned getMaxShiftAmount(const APInt &MaxValue, unsigned BitWidth) {
}
KnownBits KnownBits::shl(const KnownBits &LHS, const KnownBits &RHS, bool NUW,
- bool NSW) {
+ bool NSW, bool ShAmtNonZero) {
unsigned BitWidth = LHS.getBitWidth();
auto ShiftByConst = [&](const KnownBits &LHS, unsigned ShiftAmt) {
KnownBits Known;
@@ -198,6 +198,8 @@ KnownBits KnownBits::shl(const KnownBits &LHS, const KnownBits &RHS, bool NUW,
// Fast path for a common case when LHS is completely unknown.
KnownBits Known(BitWidth);
unsigned MinShiftAmount = RHS.getMinValue().getLimitedValue(BitWidth);
+ if (MinShiftAmount == 0 && ShAmtNonZero)
+ MinShiftAmount = 1;
if (LHS.isUnknown()) {
Known.Zero.setLowBits(MinShiftAmount);
if (NUW && NSW && MinShiftAmount != 0)
@@ -254,7 +256,8 @@ KnownBits KnownBits::shl(const KnownBits &LHS, const KnownBits &RHS, bool NUW,
return Known;
}
-KnownBits KnownBits::lshr(const KnownBits &LHS, const KnownBits &RHS) {
+KnownBits KnownBits::lshr(const KnownBits &LHS, const KnownBits &RHS,
+ bool ShAmtNonZero) {
unsigned BitWidth = LHS.getBitWidth();
auto ShiftByConst = [&](const KnownBits &LHS, unsigned ShiftAmt) {
KnownBits Known = LHS;
@@ -268,6 +271,8 @@ KnownBits KnownBits::lshr(const KnownBits &LHS, const KnownBits &RHS) {
// Fast path for a common case when LHS is completely unknown.
KnownBits Known(BitWidth);
unsigned MinShiftAmount = RHS.getMinValue().getLimitedValue(BitWidth);
+ if (MinShiftAmount == 0 && ShAmtNonZero)
+ MinShiftAmount = 1;
if (LHS.isUnknown()) {
Known.Zero.setHighBits(MinShiftAmount);
return Known;
@@ -297,7 +302,8 @@ KnownBits KnownBits::lshr(const KnownBits &LHS, const KnownBits &RHS) {
return Known;
}
-KnownBits KnownBits::ashr(const KnownBits &LHS, const KnownBits &RHS) {
+KnownBits KnownBits::ashr(const KnownBits &LHS, const KnownBits &RHS,
+ bool ShAmtNonZero) {
unsigned BitWidth = LHS.getBitWidth();
auto ShiftByConst = [&](const KnownBits &LHS, unsigned ShiftAmt) {
KnownBits Known = LHS;
@@ -309,6 +315,8 @@ KnownBits KnownBits::ashr(const KnownBits &LHS, const KnownBits &RHS) {
// Fast path for a common case when LHS is completely unknown.
KnownBits Known(BitWidth);
unsigned MinShiftAmount = RHS.getMinValue().getLimitedValue(BitWidth);
+ if (MinShiftAmount == 0 && ShAmtNonZero)
+ MinShiftAmount = 1;
if (LHS.isUnknown()) {
if (MinShiftAmount == BitWidth) {
// Always poison. Return zero because we don't like returning conflict.