summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff options
context:
space:
mode:
authorAlex Bradbury <asb@lowrisc.org>2017-12-11 11:53:54 +0000
committerAlex Bradbury <asb@lowrisc.org>2017-12-11 11:53:54 +0000
commit660bcceccf85bfc2bbac4f28b87e94c1f3e82184 (patch)
treef912cc41c2b4669b0c611f253189434ef857902d /llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
parent775bb7437932ea6141c33ab63074640fb541997e (diff)
downloadbcm5719-llvm-660bcceccf85bfc2bbac4f28b87e94c1f3e82184.tar.gz
bcm5719-llvm-660bcceccf85bfc2bbac4f28b87e94c1f3e82184.zip
[RISCV] Support lowering FrameIndex
Introduces the AddrFI "addressing mode", which is necessary simply because it's not possible to write a pattern that directly matches a frameindex. Ensure callee-saved registers are accessed relative to the stackpointer. This is necessary as callee-saved register spills are performed before the frame pointer is set. Move HexagonDAGToDAGISel::isOrEquivalentToAdd to SelectionDAGISel, so we can make use of it in the RISC-V backend. Differential Revision: https://reviews.llvm.org/D39848 llvm-svn: 320353
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 8f47c5b40ba..3a8ad51940d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3761,6 +3761,25 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
}
}
+bool SelectionDAGISel::isOrEquivalentToAdd(const SDNode *N) const {
+ assert(N->getOpcode() == ISD::OR && "Unexpected opcode");
+ auto *C = dyn_cast<ConstantSDNode>(N->getOperand(1));
+ if (!C)
+ return false;
+
+ // Detect when "or" is used to add an offset to a stack object.
+ if (auto *FN = dyn_cast<FrameIndexSDNode>(N->getOperand(0))) {
+ MachineFrameInfo &MFI = MF->getFrameInfo();
+ unsigned A = MFI.getObjectAlignment(FN->getIndex());
+ assert(isPowerOf2_32(A) && "Unexpected alignment");
+ int32_t Off = C->getSExtValue();
+ // If the alleged offset fits in the zero bits guaranteed by
+ // the alignment, then this or is really an add.
+ return (Off >= 0) && (((A - 1) & Off) == unsigned(Off));
+ }
+ return false;
+}
+
void SelectionDAGISel::CannotYetSelect(SDNode *N) {
std::string msg;
raw_string_ostream Msg(msg);
OpenPOWER on IntegriCloud