diff options
| author | Nirav Dave <niravd@google.com> | 2018-01-26 16:51:27 +0000 |
|---|---|---|
| committer | Nirav Dave <niravd@google.com> | 2018-01-26 16:51:27 +0000 |
| commit | 9896238dc979d383b23129529565adcd746bac1c (patch) | |
| tree | 439cb5b55dd46b67b8d7ce87a8872e6aa954f194 /llvm/lib | |
| parent | 706828157f0914ca5925800a22a41a0507c78271 (diff) | |
| download | bcm5719-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.cpp | 43 |
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; } |

