diff options
Diffstat (limited to 'llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | 23 |
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; + } + } } } |