summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorNirav Dave <niravd@google.com>2018-01-26 16:51:27 +0000
committerNirav Dave <niravd@google.com>2018-01-26 16:51:27 +0000
commit9896238dc979d383b23129529565adcd746bac1c (patch)
tree439cb5b55dd46b67b8d7ce87a8872e6aa954f194 /llvm/lib
parent706828157f0914ca5925800a22a41a0507c78271 (diff)
downloadbcm5719-llvm-9896238dc979d383b23129529565adcd746bac1c.tar.gz
bcm5719-llvm-9896238dc979d383b23129529565adcd746bac1c.zip
[DAG] Teach findBaseOffset to interpret indexes of indexed memory operations
Indexed outputs are addition / subtractions and can be interpreted as such. llvm-svn: 323539
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp43
1 files changed, 35 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
index da1574f6052..c859f16e74f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
@@ -99,16 +99,43 @@ BaseIndexOffset BaseIndexOffset::match(LSBaseSDNode *N,
}
// Consume constant adds & ors with appropriate masking.
- while (Base->getOpcode() == ISD::ADD || Base->getOpcode() == ISD::OR) {
- if (auto *C = dyn_cast<ConstantSDNode>(Base->getOperand(1))) {
+ while (true) {
+ switch (Base->getOpcode()) {
+ case ISD::OR:
// Only consider ORs which act as adds.
- if (Base->getOpcode() == ISD::OR &&
- !DAG.MaskedValueIsZero(Base->getOperand(0), C->getAPIntValue()))
- break;
- Offset += C->getSExtValue();
- Base = Base->getOperand(0);
- continue;
+ if (auto *C = dyn_cast<ConstantSDNode>(Base->getOperand(1)))
+ if (DAG.MaskedValueIsZero(Base->getOperand(0), C->getAPIntValue())) {
+ Offset += C->getSExtValue();
+ Base = Base->getOperand(0);
+ continue;
+ }
+ break;
+ case ISD::ADD:
+ if (auto *C = dyn_cast<ConstantSDNode>(Base->getOperand(1))) {
+ Offset += C->getSExtValue();
+ Base = Base->getOperand(0);
+ continue;
+ }
+ break;
+ case ISD::LOAD:
+ case ISD::STORE: {
+ auto *LSBase = cast<LSBaseSDNode>(Base.getNode());
+ unsigned int IndexResNo = (Base->getOpcode() == ISD::LOAD) ? 1 : 0;
+ if (LSBase->isIndexed() && Base.getResNo() == IndexResNo)
+ if (auto *C = dyn_cast<ConstantSDNode>(LSBase->getOffset())) {
+ auto Off = C->getSExtValue();
+ if (LSBase->getAddressingMode() == ISD::PRE_DEC ||
+ LSBase->getAddressingMode() == ISD::POST_DEC)
+ Offset -= Off;
+ else
+ Offset += Off;
+ Base = LSBase->getBasePtr();
+ continue;
+ }
+ break;
+ }
}
+ // If we get here break out of the loop.
break;
}
OpenPOWER on IntegriCloud