diff options
author | Momchil Velikov <momchil.velikov@arm.com> | 2018-01-08 14:47:19 +0000 |
---|---|---|
committer | Momchil Velikov <momchil.velikov@arm.com> | 2018-01-08 14:47:19 +0000 |
commit | ac7c5c1d92f9c965e23b95c6e930fc85cdfbbfaa (patch) | |
tree | 5e029fe9723c7b67832458a071ab03da0e096cfc /llvm/lib/Target | |
parent | 31db71361549c0428b683462a83beb94dbaae4ac (diff) | |
download | bcm5719-llvm-ac7c5c1d92f9c965e23b95c6e930fc85cdfbbfaa.tar.gz bcm5719-llvm-ac7c5c1d92f9c965e23b95c6e930fc85cdfbbfaa.zip |
[ARM] Fix PR35379 - incorrect unwind information when compiling with -Oz
The patch makes the unwind information not mention registers, which were pushed
solely for the purpose of saving stack adjustment instructions.
Differential revision: https://reviews.llvm.org/D41300
Fixes https://bugs.llvm.org/show_bug.cgi?id=35379
llvm-svn: 321996
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; |