From e9b88c754ad31bcc0dd582a04402b5de1a28ef48 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Tue, 3 Nov 2020 18:09:15 +0000 Subject: [PATCH] [DAG] computeKnownBits - Move ISD::SRA handling into KnownBits::ashr As discussed on D90527, we should be trying to move shift handling functionality into KnownBits to avoid code duplication in SelectionDAG/GlobalISel/ValueTracking. --- llvm/include/llvm/Support/KnownBits.h | 4 ++++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 11 ++++------- llvm/lib/Support/KnownBits.cpp | 17 +++++++++++++++++ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/llvm/include/llvm/Support/KnownBits.h b/llvm/include/llvm/Support/KnownBits.h index da8b099..e534141 100644 --- a/llvm/include/llvm/Support/KnownBits.h +++ b/llvm/include/llvm/Support/KnownBits.h @@ -278,6 +278,10 @@ public: /// NOTE: RHS (shift amount) bitwidth doesn't need to be the same as LHS. static KnownBits lshr(const KnownBits &LHS, const KnownBits &RHS); + /// Compute known bits for ashr(LHS, RHS). + /// NOTE: RHS (shift amount) bitwidth doesn't need to be the same as LHS. + static KnownBits ashr(const KnownBits &LHS, const KnownBits &RHS); + /// Insert the bits from a smaller known bits starting at bitPosition. void insertBits(const KnownBits &SubBits, unsigned BitPosition) { Zero.insertBits(SubBits.Zero, BitPosition); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index a1e1041..89ded9e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2979,13 +2979,10 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts, Known.Zero.setHighBits(ShMinAmt->getZExtValue()); break; case ISD::SRA: - if (const APInt *ShAmt = getValidShiftAmountConstant(Op, DemandedElts)) { - Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1); - unsigned Shift = ShAmt->getZExtValue(); - // Sign extend known zero/one bit (else is unknown). - Known.Zero.ashrInPlace(Shift); - Known.One.ashrInPlace(Shift); - } + Known = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1); + Known2 = computeKnownBits(Op.getOperand(1), DemandedElts, Depth + 1); + Known = KnownBits::ashr(Known, Known2); + // TODO: Add minimum shift high known sign bits. break; case ISD::FSHL: case ISD::FSHR: diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp index c270b48..0c88ca6 100644 --- a/llvm/lib/Support/KnownBits.cpp +++ b/llvm/lib/Support/KnownBits.cpp @@ -192,6 +192,23 @@ KnownBits KnownBits::lshr(const KnownBits &LHS, const KnownBits &RHS) { return Known; } +KnownBits KnownBits::ashr(const KnownBits &LHS, const KnownBits &RHS) { + unsigned BitWidth = LHS.getBitWidth(); + KnownBits Known(BitWidth); + + if (RHS.isConstant() && RHS.getConstant().ult(BitWidth)) { + unsigned Shift = RHS.getConstant().getZExtValue(); + Known = LHS; + Known.Zero.ashrInPlace(Shift); + Known.One.ashrInPlace(Shift); + return Known; + } + + // TODO: Minimum shift amount high bits are known sign bits. + // TODO: No matter the shift amount, the leading sign bits will stay. + return Known; +} + KnownBits KnownBits::abs() const { // If the source's MSB is zero then we know the rest of the bits already. if (isNonNegative()) -- 2.7.4