diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 75f5f392a5bf17..92a547c542b1b1 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -1790,15 +1790,23 @@ bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand( return true; } -// Select a frame index and an optional immediate offset from an ADD or OR. -bool RISCVDAGToDAGISel::SelectFrameAddrRegImm(SDValue Addr, SDValue &Base, - SDValue &Offset) { +bool RISCVDAGToDAGISel::SelectAddrFrameIndex(SDValue Addr, SDValue &Base, + SDValue &Offset) { if (auto *FIN = dyn_cast(Addr)) { Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), Subtarget->getXLenVT()); Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Subtarget->getXLenVT()); return true; } + return false; +} + +// Select a frame index and an optional immediate offset from an ADD or OR. +bool RISCVDAGToDAGISel::SelectFrameAddrRegImm(SDValue Addr, SDValue &Base, + SDValue &Offset) { + if (SelectAddrFrameIndex(Addr, Base, Offset)) + return true; + if (!CurDAG->isBaseWithConstantOffset(Addr)) return false; @@ -1828,17 +1836,25 @@ bool RISCVDAGToDAGISel::SelectBaseAddr(SDValue Addr, SDValue &Base) { bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset) { + if (SelectAddrFrameIndex(Addr, Base, Offset)) + return true; + if (CurDAG->isBaseWithConstantOffset(Addr)) { auto *CN = cast(Addr.getOperand(1)); if (isInt<12>(CN->getSExtValue())) { + Base = Addr.getOperand(0); + if (auto *FIN = dyn_cast(Base)) + Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), + Subtarget->getXLenVT()); Offset = CurDAG->getTargetConstant(CN->getSExtValue(), SDLoc(Addr), Subtarget->getXLenVT()); - return SelectBaseAddr(Addr.getOperand(0), Base); + return true; } } + Base = Addr; Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Subtarget->getXLenVT()); - return SelectBaseAddr(Addr, Base); + return true; } bool RISCVDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth, diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h index d4eadb5f1b3ecd..b50927cfcca531 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h @@ -45,6 +45,7 @@ class RISCVDAGToDAGISel : public SelectionDAGISel { bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID, std::vector &OutOps) override; + bool SelectAddrFrameIndex(SDValue Addr, SDValue &Base, SDValue &Offset); bool SelectFrameAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset); bool SelectBaseAddr(SDValue Addr, SDValue &Base); bool SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset);