summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp23
1 files changed, 15 insertions, 8 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 127d86c9138..c9a88823f5e 100644
--- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -1150,15 +1150,22 @@ bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue N,
if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/4, 0, 256, RHSC)) {
Base = N.getOperand(0);
int FI = cast<FrameIndexSDNode>(Base)->getIndex();
- // For LHS+RHS to result in an offset that's a multiple of 4 the object
- // indexed by the LHS must be 4-byte aligned.
+ // Make sure the offset is inside the object, or we might fail to
+ // allocate an emergency spill slot. (An out-of-range access is UB, but
+ // it could show up anyway.)
MachineFrameInfo &MFI = MF->getFrameInfo();
- if (MFI.getObjectAlignment(FI) < 4)
- MFI.setObjectAlignment(FI, 4);
- Base = CurDAG->getTargetFrameIndex(
- FI, TLI->getPointerTy(CurDAG->getDataLayout()));
- OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i32);
- return true;
+ if (RHSC * 4 < MFI.getObjectSize(FI)) {
+ // For LHS+RHS to result in an offset that's a multiple of 4 the object
+ // indexed by the LHS must be 4-byte aligned.
+ if (!MFI.isFixedObjectIndex(FI) && MFI.getObjectAlignment(FI) < 4)
+ MFI.setObjectAlignment(FI, 4);
+ if (MFI.getObjectAlignment(FI) >= 4) {
+ Base = CurDAG->getTargetFrameIndex(
+ FI, TLI->getPointerTy(CurDAG->getDataLayout()));
+ OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i32);
+ return true;
+ }
+ }
}
}
OpenPOWER on IntegriCloud