summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
diff options
context:
space:
mode:
authorNirav Dave <niravd@google.com>2018-01-08 16:21:35 +0000
committerNirav Dave <niravd@google.com>2018-01-08 16:21:35 +0000
commit6e2d03d4103d1b2032fc18343f8b13568eaefddb (patch)
treeb77fed9b6d36f8f3417b63c43d66f90491996ea4 /llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
parent1092ceae556bf36c3691d2d476f62711157f5257 (diff)
downloadbcm5719-llvm-6e2d03d4103d1b2032fc18343f8b13568eaefddb.tar.gz
bcm5719-llvm-6e2d03d4103d1b2032fc18343f8b13568eaefddb.zip
[DAG] Teach BaseIndexOffset to correctly handle with indexed operations
BaseIndexOffset address analysis incorrectly ignores offsets folded into indexed memory operations causing potential errors in alias analysis of pre-indexed operations. Reviewers: efriedma, RKSimon, hfinkel, jyknight Subscribers: hiraditya, javed.absar, llvm-commits Differential Revision: https://reviews.llvm.org/D41701 llvm-svn: 322003
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp21
1 files changed, 20 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
index d5980919d03..da1574f6052 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGAddressAnalysis.cpp
@@ -21,6 +21,9 @@ using namespace llvm;
bool BaseIndexOffset::equalBaseIndex(BaseIndexOffset &Other,
const SelectionDAG &DAG, int64_t &Off) {
+ // Conservatively fail if we a match failed..
+ if (!Base.getNode() || !Other.Base.getNode())
+ return false;
// Initial Offset difference.
Off = Other.Offset - Offset;
@@ -72,13 +75,29 @@ bool BaseIndexOffset::equalBaseIndex(BaseIndexOffset &Other,
}
/// Parses tree in Ptr for base, index, offset addresses.
-BaseIndexOffset BaseIndexOffset::match(SDValue Ptr, const SelectionDAG &DAG) {
+BaseIndexOffset BaseIndexOffset::match(LSBaseSDNode *N,
+ const SelectionDAG &DAG) {
+ SDValue Ptr = N->getBasePtr();
+
// (((B + I*M) + c)) + c ...
SDValue Base = DAG.getTargetLoweringInfo().unwrapAddress(Ptr);
SDValue Index = SDValue();
int64_t Offset = 0;
bool IsIndexSignExt = false;
+ // pre-inc/pre-dec ops are components of EA.
+ if (N->getAddressingMode() == ISD::PRE_INC) {
+ if (auto *C = dyn_cast<ConstantSDNode>(N->getOffset()))
+ Offset += C->getSExtValue();
+ else // If unknown, give up now.
+ return BaseIndexOffset(SDValue(), SDValue(), 0, false);
+ } else if (N->getAddressingMode() == ISD::PRE_DEC) {
+ if (auto *C = dyn_cast<ConstantSDNode>(N->getOffset()))
+ Offset -= C->getSExtValue();
+ else // If unknown, give up now.
+ return BaseIndexOffset(SDValue(), SDValue(), 0, false);
+ }
+
// 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))) {
OpenPOWER on IntegriCloud