Skip to content

Commit d32ed9b

Browse files
committed
[RISCV] Use a ComplexPattern to merge the PatFrags for removing unneeded masks on shift amounts.
Rather than having patterns with and without an AND, use a ComplexPattern to handle both cases. Reduces the isel table by about 700 bytes.
1 parent c40b831 commit d32ed9b

File tree

3 files changed

+41
-25
lines changed

3 files changed

+41
-25
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -925,19 +925,35 @@ bool RISCVDAGToDAGISel::SelectRVVBaseAddr(SDValue Addr, SDValue &Base) {
925925
return true;
926926
}
927927

928-
// Helper to detect unneeded and instructions on shift amounts. Called
929-
// from PatFrags in tablegen.
930-
bool RISCVDAGToDAGISel::isUnneededShiftMask(SDNode *N, unsigned Width) const {
931-
assert(N->getOpcode() == ISD::AND && "Unexpected opcode");
932-
assert(Width >= 5 && N->getValueSizeInBits(0) >= (1ULL << Width) &&
933-
"Unexpected width");
934-
const APInt &Val = N->getConstantOperandAPInt(1);
935-
936-
if (Val.countTrailingOnes() >= Width)
937-
return true;
928+
bool RISCVDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth,
929+
SDValue &ShAmt) {
930+
// Shift instructions on RISCV only read the lower 5 or 6 bits of the shift
931+
// amount. If there is an AND on the shift amount, we can bypass it if it
932+
// doesn't affect any of those bits.
933+
if (N.getOpcode() == ISD::AND && isa<ConstantSDNode>(N.getOperand(1))) {
934+
const APInt &AndMask = N->getConstantOperandAPInt(1);
935+
936+
// Since the max shift amount is a power of 2 we can subtract 1 to make a
937+
// mask that covers the bits needed to represent all shift amounts.
938+
assert(isPowerOf2_32(ShiftWidth) && "Unexpected max shift amount!");
939+
APInt ShMask(AndMask.getBitWidth(), ShiftWidth - 1);
940+
941+
if (ShMask.isSubsetOf(AndMask)) {
942+
ShAmt = N.getOperand(0);
943+
return true;
944+
}
945+
946+
// SimplifyDemandedBits may have optimized the mask so try restoring any
947+
// bits that are known zero.
948+
KnownBits Known = CurDAG->computeKnownBits(N->getOperand(0));
949+
if (ShMask.isSubsetOf(AndMask | Known.Zero)) {
950+
ShAmt = N.getOperand(0);
951+
return true;
952+
}
953+
}
938954

939-
APInt Mask = Val | CurDAG->computeKnownBits(N->getOperand(0)).Zero;
940-
return Mask.countTrailingOnes() >= Width;
955+
ShAmt = N;
956+
return true;
941957
}
942958

943959
// Match (srl (and val, mask), imm) where the result would be a

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,13 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
4646
bool SelectAddrFI(SDValue Addr, SDValue &Base);
4747
bool SelectRVVBaseAddr(SDValue Addr, SDValue &Base);
4848

49-
bool isUnneededShiftMask(SDNode *N, unsigned Width) const;
49+
bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt);
50+
bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt) {
51+
return selectShiftMask(N, Subtarget->getXLen(), ShAmt);
52+
}
53+
bool selectShiftMask32(SDValue N, SDValue &ShAmt) {
54+
return selectShiftMask(N, 32, ShAmt);
55+
}
5056

5157
bool MatchSRLIW(SDNode *N) const;
5258
bool MatchSLLIUW(SDNode *N) const;

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -895,21 +895,15 @@ def : PatGprUimmLog2XLen<sra, SRAI>;
895895
// typically introduced when the legalizer promotes the shift amount and
896896
// zero-extends it). For RISC-V, the mask is unnecessary as shifts in the base
897897
// ISA only read the least significant 5 bits (RV32I) or 6 bits (RV64I).
898-
def shiftMaskXLen : PatFrag<(ops node:$lhs), (and node:$lhs, imm), [{
899-
return isUnneededShiftMask(N, Subtarget->is64Bit() ? 6 : 5);
900-
}]>;
901-
def shiftMask32 : PatFrag<(ops node:$lhs), (and node:$lhs, imm), [{
902-
return isUnneededShiftMask(N, 5);
903-
}]>;
898+
def shiftMaskXLen : ComplexPattern<XLenVT, 1, "selectShiftMaskXLen", [], [], 0>;
899+
def shiftMask32 : ComplexPattern<i64, 1, "selectShiftMask32", [], [], 0>;
904900

905901
class shiftop<SDPatternOperator operator>
906-
: PatFrags<(ops node:$val, node:$count),
907-
[(operator node:$val, node:$count),
908-
(operator node:$val, (shiftMaskXLen node:$count))]>;
902+
: PatFrag<(ops node:$val, node:$count),
903+
(operator node:$val, (XLenVT (shiftMaskXLen node:$count)))>;
909904
class shiftopw<SDPatternOperator operator>
910-
: PatFrags<(ops node:$val, node:$count),
911-
[(operator node:$val, node:$count),
912-
(operator node:$val, (shiftMask32 node:$count))]>;
905+
: PatFrag<(ops node:$val, node:$count),
906+
(operator node:$val, (i64 (shiftMask32 node:$count)))>;
913907

914908
def : PatGprGpr<shiftop<shl>, SLL>;
915909
def : PatGprGpr<shiftop<srl>, SRL>;

0 commit comments

Comments
 (0)