[llvm] c2d18d7 - [KnownBits] Add min/max shift amount handling to shl/lshr/ashr KnownBits helpers
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 8 03:44:48 PST 2021
Author: Simon Pilgrim
Date: 2021-03-08T11:44:31Z
New Revision: c2d18d700500991eff15ac674dacdeb3e1d8c21d
URL: https://github.com/llvm/llvm-project/commit/c2d18d700500991eff15ac674dacdeb3e1d8c21d
DIFF: https://github.com/llvm/llvm-project/commit/c2d18d700500991eff15ac674dacdeb3e1d8c21d.diff
LOG: [KnownBits] Add min/max shift amount handling to shl/lshr/ashr KnownBits helpers
Pulled out of the original D90479 patch - also includes the "impossible shift amount" filtering from computeKnownBitsFromShiftOperator.
Differential Revision: https://reviews.llvm.org/D90479
Added:
Modified:
llvm/lib/Support/KnownBits.cpp
llvm/test/Transforms/InstSimplify/icmp-constant.ll
Removed:
################################################################################
diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp
index d7265d03d27d..6c7aaad968f5 100644
--- a/llvm/lib/Support/KnownBits.cpp
+++ b/llvm/lib/Support/KnownBits.cpp
@@ -187,6 +187,31 @@ KnownBits KnownBits::shl(const KnownBits &LHS, const KnownBits &RHS) {
MinTrailingZeros = std::min(MinTrailingZeros, BitWidth);
}
+ // If the maximum shift is in range, then find the common bits from all
+ // possible shifts.
+ APInt MaxShiftAmount = RHS.getMaxValue();
+ if (MaxShiftAmount.ult(BitWidth) && !LHS.isUnknown()) {
+ uint64_t ShiftAmtZeroMask = (~RHS.Zero).getZExtValue();
+ uint64_t ShiftAmtOneMask = RHS.One.getZExtValue();
+ assert(MinShiftAmount.ult(MaxShiftAmount) && "Illegal shift range");
+ Known.Zero.setAllBits();
+ Known.One.setAllBits();
+ for (uint64_t ShiftAmt = MinShiftAmount.getZExtValue(),
+ MaxShiftAmt = MaxShiftAmount.getZExtValue();
+ ShiftAmt <= MaxShiftAmt; ++ShiftAmt) {
+ // Skip if the shift amount is impossible.
+ if ((ShiftAmtZeroMask & ShiftAmt) != ShiftAmt ||
+ (ShiftAmtOneMask | ShiftAmt) != ShiftAmt)
+ continue;
+ KnownBits SpecificShift;
+ SpecificShift.Zero = LHS.Zero << ShiftAmt;
+ SpecificShift.One = LHS.One << ShiftAmt;
+ Known = KnownBits::commonBits(Known, SpecificShift);
+ if (Known.isUnknown())
+ break;
+ }
+ }
+
Known.Zero.setLowBits(MinTrailingZeros);
return Known;
}
@@ -215,6 +240,31 @@ KnownBits KnownBits::lshr(const KnownBits &LHS, const KnownBits &RHS) {
MinLeadingZeros = std::min(MinLeadingZeros, BitWidth);
}
+ // If the maximum shift is in range, then find the common bits from all
+ // possible shifts.
+ APInt MaxShiftAmount = RHS.getMaxValue();
+ if (MaxShiftAmount.ult(BitWidth) && !LHS.isUnknown()) {
+ uint64_t ShiftAmtZeroMask = (~RHS.Zero).getZExtValue();
+ uint64_t ShiftAmtOneMask = RHS.One.getZExtValue();
+ assert(MinShiftAmount.ult(MaxShiftAmount) && "Illegal shift range");
+ Known.Zero.setAllBits();
+ Known.One.setAllBits();
+ for (uint64_t ShiftAmt = MinShiftAmount.getZExtValue(),
+ MaxShiftAmt = MaxShiftAmount.getZExtValue();
+ ShiftAmt <= MaxShiftAmt; ++ShiftAmt) {
+ // Skip if the shift amount is impossible.
+ if ((ShiftAmtZeroMask & ShiftAmt) != ShiftAmt ||
+ (ShiftAmtOneMask | ShiftAmt) != ShiftAmt)
+ continue;
+ KnownBits SpecificShift = LHS;
+ SpecificShift.Zero.lshrInPlace(ShiftAmt);
+ SpecificShift.One.lshrInPlace(ShiftAmt);
+ Known = KnownBits::commonBits(Known, SpecificShift);
+ if (Known.isUnknown())
+ break;
+ }
+ }
+
Known.Zero.setHighBits(MinLeadingZeros);
return Known;
}
@@ -248,6 +298,31 @@ KnownBits KnownBits::ashr(const KnownBits &LHS, const KnownBits &RHS) {
}
}
+ // If the maximum shift is in range, then find the common bits from all
+ // possible shifts.
+ APInt MaxShiftAmount = RHS.getMaxValue();
+ if (MaxShiftAmount.ult(BitWidth) && !LHS.isUnknown()) {
+ uint64_t ShiftAmtZeroMask = (~RHS.Zero).getZExtValue();
+ uint64_t ShiftAmtOneMask = RHS.One.getZExtValue();
+ assert(MinShiftAmount.ult(MaxShiftAmount) && "Illegal shift range");
+ Known.Zero.setAllBits();
+ Known.One.setAllBits();
+ for (uint64_t ShiftAmt = MinShiftAmount.getZExtValue(),
+ MaxShiftAmt = MaxShiftAmount.getZExtValue();
+ ShiftAmt <= MaxShiftAmt; ++ShiftAmt) {
+ // Skip if the shift amount is impossible.
+ if ((ShiftAmtZeroMask & ShiftAmt) != ShiftAmt ||
+ (ShiftAmtOneMask | ShiftAmt) != ShiftAmt)
+ continue;
+ KnownBits SpecificShift = LHS;
+ SpecificShift.Zero.ashrInPlace(ShiftAmt);
+ SpecificShift.One.ashrInPlace(ShiftAmt);
+ Known = KnownBits::commonBits(Known, SpecificShift);
+ if (Known.isUnknown())
+ break;
+ }
+ }
+
Known.Zero.setHighBits(MinLeadingZeros);
Known.One.setHighBits(MinLeadingOnes);
return Known;
diff --git a/llvm/test/Transforms/InstSimplify/icmp-constant.ll b/llvm/test/Transforms/InstSimplify/icmp-constant.ll
index f8d5bdc89ceb..9db63e64b914 100644
--- a/llvm/test/Transforms/InstSimplify/icmp-constant.ll
+++ b/llvm/test/Transforms/InstSimplify/icmp-constant.ll
@@ -799,7 +799,7 @@ define i1 @eq_shl_by_constant_produces_poison(i8 %x) {
define i1 @eq_shl_by_variable_produces_poison(i8 %x) {
; CHECK-LABEL: @eq_shl_by_variable_produces_poison(
-; CHECK-NEXT: ret i1 false
+; CHECK-NEXT: ret i1 poison
;
%clear_high_bit = and i8 %x, 127 ; 0x7f
%set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70
More information about the llvm-commits
mailing list