diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 18 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | 6 |
2 files changed, 20 insertions, 4 deletions
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index d3d79fe975b..e50bbc19515 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -1086,6 +1086,8 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { unsigned StartOp = 2 + 2; // Use all the operands. unsigned NumOffset = 0; + // Amount of SP adjustment folded into a push. + unsigned Pad = 0; switch (Opc) { default: @@ -1107,6 +1109,16 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { // temporary to workaround PR11902. if (MO.isImplicit()) continue; + // Registers, pushed as a part of folding an SP update into the + // push instruction are marked as undef and should not be + // restored when unwinding, because the function can modify the + // corresponding stack slots. + if (MO.isUndef()) { + assert(RegList.empty() && + "Pad registers must come before restored ones"); + Pad += 4; + continue; + } RegList.push_back(MO.getReg()); } break; @@ -1118,8 +1130,12 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { RegList.push_back(SrcReg); break; } - if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM) + if (MAI->getExceptionHandlingType() == ExceptionHandling::ARM) { ATS.emitRegSave(RegList, Opc == ARM::VSTMDDB_UPD); + // Account for the SP adjustment, folded into the push. + if (Pad) + ATS.emitPad(Pad); + } } else { // Changes of stack / frame pointer. if (SrcReg == ARM::SP) { diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index 8c1727724a9..7bf47ab6060 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -2277,9 +2277,9 @@ bool llvm::tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget, --CurRegEnc) { unsigned CurReg = RegClass->getRegister(CurRegEnc); if (!IsPop) { - // Pushing any register is completely harmless, mark the - // register involved as undef since we don't care about it in - // the slightest. + // Pushing any register is completely harmless, mark the register involved + // as undef since we don't care about its value and must not restore it + // during stack unwinding. RegList.push_back(MachineOperand::CreateReg(CurReg, false, false, false, false, true)); --RegsNeeded; |