[llvm] 4402852 - [RISCV] Reduce scalar load/store isel patterns to a single ComplexPattern. NFCI
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 3 09:01:30 PDT 2022
Author: Craig Topper
Date: 2022-06-03T09:00:17-07:00
New Revision: 440285200265eca0e148cb838f83fa7cbc37c640
URL: https://github.com/llvm/llvm-project/commit/440285200265eca0e148cb838f83fa7cbc37c640
DIFF: https://github.com/llvm/llvm-project/commit/440285200265eca0e148cb838f83fa7cbc37c640.diff
LOG: [RISCV] Reduce scalar load/store isel patterns to a single ComplexPattern. NFCI
Previously we had 3 different isel patterns for every scalar load
store instruction.
This reduces them to a single ComplexPattern that returns the Base
and Offset. Or an offset of 0 if there was no offset identified
I've done a similar thing for the 2 isel patterns that match add/or
with FrameIndex and immediate. Using the offset of 0, I was also
able to remove the custom handler for FrameIndex. Happy to split that
to another patch.
We might be able to enhance in the future to remove the post-isel
peephole or the special handling for ADD with constant added by D126576.
A nice side effect is that this removes nearly 3000 bytes from the isel
table.
Differential Revision: https://reviews.llvm.org/D126932
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
llvm/lib/Target/RISCV/RISCVInstrInfo.td
llvm/lib/Target/RISCV/RISCVInstrInfoA.td
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index b6606161c491f..6ddb75337bb90 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -691,13 +691,6 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
ReplaceNode(Node, selectImm(CurDAG, DL, VT, Imm, *Subtarget));
return;
}
- case ISD::FrameIndex: {
- SDValue Imm = CurDAG->getTargetConstant(0, DL, XLenVT);
- int FI = cast<FrameIndexSDNode>(Node)->getIndex();
- SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
- ReplaceNode(Node, CurDAG->getMachineNode(RISCV::ADDI, DL, VT, TFI, Imm));
- return;
- }
case ISD::ADD: {
// Try to select ADD + immediate used as memory addresses to
// (ADDI (ADD X, Imm-Lo12), Lo12) if it will allow the ADDI to be removed by
@@ -1861,11 +1854,31 @@ bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand(
return true;
}
-bool RISCVDAGToDAGISel::SelectAddrFI(SDValue Addr, SDValue &Base) {
+// Select a frame index and an optional immediate offset from an ADD or OR.
+bool RISCVDAGToDAGISel::SelectFrameAddrRegImm(SDValue Addr, SDValue &Base,
+ SDValue &Offset) {
if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT());
+ Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Subtarget->getXLenVT());
return true;
}
+
+ // TODO: Use SelectionDAG::isBaseWithConstantOffset.
+ if (Addr.getOpcode() == ISD::ADD ||
+ (Addr.getOpcode() == ISD::OR && isOrEquivalentToAdd(Addr.getNode()))) {
+ if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
+ if (auto *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
+ if (isInt<12>(CN->getSExtValue())) {
+ Base = CurDAG->getTargetFrameIndex(FIN->getIndex(),
+ Subtarget->getXLenVT());
+ Offset = CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(Addr),
+ Subtarget->getXLenVT());
+ return true;
+ }
+ }
+ }
+ }
+
return false;
}
@@ -1879,6 +1892,38 @@ bool RISCVDAGToDAGISel::SelectBaseAddr(SDValue Addr, SDValue &Base) {
return true;
}
+bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
+ SDValue &Offset) {
+ if (Addr.getOpcode() == ISD::ADD) {
+ if (auto *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
+ if (isInt<12>(CN->getSExtValue())) {
+ SelectBaseAddr(Addr.getOperand(0), Base);
+ Offset = CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(Addr),
+ Subtarget->getXLenVT());
+ return true;
+ }
+ }
+ } else if (Addr.getOpcode() == ISD::OR) {
+ // We might be able to treat this OR as an ADD.
+ // TODO: Use SelectionDAG::isBaseWithConstantOffset.
+ if (auto *FIN = dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
+ if (auto *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
+ if (isInt<12>(CN->getSExtValue()) &&
+ isOrEquivalentToAdd(Addr.getNode())) {
+ Base = CurDAG->getTargetFrameIndex(FIN->getIndex(),
+ Subtarget->getXLenVT());
+ Offset = CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(Addr),
+ Subtarget->getXLenVT());
+ return true;
+ }
+ }
+ }
+ }
+
+ Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Subtarget->getXLenVT());
+ return SelectBaseAddr(Addr, Base);
+}
+
bool RISCVDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth,
SDValue &ShAmt) {
// Shift instructions on RISCV only read the lower 5 or 6 bits of the shift
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
index 8ddc5c32a3da2..d4eadb5f1b3ec 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
@@ -45,8 +45,9 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
std::vector<SDValue> &OutOps) override;
- bool SelectAddrFI(SDValue Addr, SDValue &Base);
+ bool SelectFrameAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset);
bool SelectBaseAddr(SDValue Addr, SDValue &Base);
+ bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset);
bool selectShiftMask(SDValue N, unsigned ShiftWidth, SDValue &ShAmt);
bool selectShiftMaskXLen(SDValue N, SDValue &ShAmt) {
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 5034e380c9ae4..f6f85ab9a6bdb 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -367,8 +367,10 @@ def uimm6gt32 : ImmLeaf<XLenVT, [{
// Addressing modes.
// Necessary because a frameindex can't be matched directly in a pattern.
-def AddrFI : ComplexPattern<iPTR, 1, "SelectAddrFI">;
+def FrameAddrRegImm : ComplexPattern<iPTR, 2, "SelectFrameAddrRegImm",
+ [frameindex, or, add]>;
def BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">;
+def AddrRegImm : ComplexPattern<iPTR, 2, "SelectAddrRegImm">;
// Return the negation of an immediate value.
def NegImm : SDNodeXForm<imm, [{
@@ -1115,9 +1117,6 @@ class PatGprUimmLog2XLen<SDPatternOperator OpNode, RVInstIShift Inst>
/// Predicates
-def IsOrAdd: PatFrag<(ops node:$A, node:$B), (or node:$A, node:$B), [{
- return isOrEquivalentToAdd(N);
-}]>;
def assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{
return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);
}]>;
@@ -1205,10 +1204,8 @@ def PseudoAddTPRel : Pseudo<(outs GPR:$rd),
/// FrameIndex calculations
-def : Pat<(add (XLenVT AddrFI:$Rs), simm12:$imm12),
- (ADDI (XLenVT AddrFI:$Rs), simm12:$imm12)>;
-def : Pat<(IsOrAdd (XLenVT AddrFI:$Rs), simm12:$imm12),
- (ADDI (XLenVT AddrFI:$Rs), simm12:$imm12)>;
+def : Pat<(FrameAddrRegImm GPR:$rs1, simm12:$imm12),
+ (ADDI GPR:$rs1, simm12:$imm12)>;
/// Setcc
@@ -1397,11 +1394,8 @@ def PseudoZEXT_W : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "zext.w", "$rd, $rs
/// Loads
multiclass LdPat<PatFrag LoadOp, RVInst Inst, ValueType vt = XLenVT> {
- def : Pat<(vt (LoadOp BaseAddr:$rs1)), (Inst BaseAddr:$rs1, 0)>;
- def : Pat<(vt (LoadOp (add BaseAddr:$rs1, simm12:$imm12))),
- (Inst BaseAddr:$rs1, simm12:$imm12)>;
- def : Pat<(vt (LoadOp (IsOrAdd AddrFI:$rs1, simm12:$imm12))),
- (Inst AddrFI:$rs1, simm12:$imm12)>;
+ def : Pat<(vt (LoadOp (AddrRegImm GPR:$rs1, simm12:$imm12))),
+ (Inst GPR:$rs1, simm12:$imm12)>;
}
defm : LdPat<sextloadi8, LB>;
@@ -1416,12 +1410,8 @@ defm : LdPat<zextloadi16, LHU>;
multiclass StPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
ValueType vt> {
- def : Pat<(StoreOp (vt StTy:$rs2), BaseAddr:$rs1),
- (Inst StTy:$rs2, BaseAddr:$rs1, 0)>;
- def : Pat<(StoreOp (vt StTy:$rs2), (add BaseAddr:$rs1, simm12:$imm12)),
- (Inst StTy:$rs2, BaseAddr:$rs1, simm12:$imm12)>;
- def : Pat<(StoreOp (vt StTy:$rs2), (IsOrAdd AddrFI:$rs1, simm12:$imm12)),
- (Inst StTy:$rs2, AddrFI:$rs1, simm12:$imm12)>;
+ def : Pat<(StoreOp (vt StTy:$rs2), (AddrRegImm GPR:$rs1, simm12:$imm12)),
+ (Inst StTy:$rs2, GPR:$rs1, simm12:$imm12)>;
}
defm : StPat<truncstorei8, SB, GPR, XLenVT>;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoA.td b/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
index eaef8cdc2fb89..dd4b174d7e62f 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoA.td
@@ -45,12 +45,8 @@ multiclass AMO_rr_aq_rl<bits<5> funct5, bits<3> funct3, string opcodestr> {
multiclass AtomicStPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
ValueType vt = XLenVT> {
- def : Pat<(StoreOp BaseAddr:$rs1, (vt StTy:$rs2)),
- (Inst StTy:$rs2, BaseAddr:$rs1, 0)>;
- def : Pat<(StoreOp (add BaseAddr:$rs1, simm12:$imm12), (vt StTy:$rs2)),
- (Inst StTy:$rs2, BaseAddr:$rs1, simm12:$imm12)>;
- def : Pat<(StoreOp (IsOrAdd AddrFI:$rs1, simm12:$imm12), (vt StTy:$rs2)),
- (Inst StTy:$rs2, AddrFI:$rs1, simm12:$imm12)>;
+ def : Pat<(StoreOp (AddrRegImm GPR:$rs1, simm12:$imm12), (vt StTy:$rs2)),
+ (Inst StTy:$rs2, GPR:$rs1, simm12:$imm12)>;
}
//===----------------------------------------------------------------------===//
More information about the llvm-commits
mailing list