summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2017-12-04 05:38:42 +0000
committerCraig Topper <craig.topper@intel.com>2017-12-04 05:38:42 +0000
commit67217d7eb474982c34d807acae60708466b9f519 (patch)
tree75d68ea9c6645cb1148106ca37da43f8d9d8d8c2 /llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
parenta565a7b9b835656746d82425721d0f0eb69e3113 (diff)
downloadbcm5719-llvm-67217d7eb474982c34d807acae60708466b9f519.tar.gz
bcm5719-llvm-67217d7eb474982c34d807acae60708466b9f519.zip
[SelectionDAG] Teach computeKnownBits some improvements to ISD::SRL with a non-splat constant shift amount.
If we have a non-splat constant shift amount, the minimum shift amount can be used to infer the number of zero upper bits of the result. There's probably a lot more that we can do here, but this fixes a case where I wanted to infer the sign bit as zero when all the shift amounts are non-zero. llvm-svn: 319639
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 0b59af2fa10..bcc972e0b4f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -2478,6 +2478,25 @@ void SelectionDAG::computeKnownBits(SDValue Op, KnownBits &Known,
Known.One.lshrInPlace(Shift);
// High bits are known zero.
Known.Zero.setHighBits(Shift);
+ } else if (auto *BV = dyn_cast<BuildVectorSDNode>(Op.getOperand(1))) {
+ // If the shift amount is a vector of constants see if we can bound
+ // the number of upper zero bits.
+ unsigned ShiftAmountMin = BitWidth;
+ for (unsigned i = 0; i != BV->getNumOperands(); ++i) {
+ if (auto *C = dyn_cast<ConstantSDNode>(BV->getOperand(i))) {
+ const APInt &ShAmt = C->getAPIntValue();
+ if (ShAmt.ult(BitWidth)) {
+ ShiftAmountMin = std::min<unsigned>(ShiftAmountMin,
+ ShAmt.getZExtValue());
+ continue;
+ }
+ }
+ // Don't know anything.
+ ShiftAmountMin = 0;
+ break;
+ }
+
+ Known.Zero.setHighBits(ShiftAmountMin);
}
break;
case ISD::SRA:
OpenPOWER on IntegriCloud