diff options
| author | Eli Friedman <efriedma@quicinc.com> | 2019-07-02 21:35:15 +0000 |
|---|---|---|
| committer | Eli Friedman <efriedma@quicinc.com> | 2019-07-02 21:35:15 +0000 |
| commit | e97aa961d3255d95c32bb884858ccdd3a00dbadc (patch) | |
| tree | d7edf22fc10a04223a81ff618de11f67ae651dc1 /llvm/lib | |
| parent | 10ee3ac396f5d3f4251748d7973bf22faf9fbef9 (diff) | |
| download | bcm5719-llvm-e97aa961d3255d95c32bb884858ccdd3a00dbadc.tar.gz bcm5719-llvm-e97aa961d3255d95c32bb884858ccdd3a00dbadc.zip | |
[ARM] Fix unwind info for Thumb1 functions that save high registers.
There were two issues here: one, some of the relevant instructions were
missing the expected "FrameSetup" flag, and two,
ARMAsmPrinter::EmitUnwindingInstruction wasn't expecting "mov"
instructions in the prologue.
I'm sticking the additional state into ARMFunctionInfo so it's obvious
it only applies to the current function.
I considered a few alternative approaches where we would compute the
correct unwind information as part of the prologue/epilogue lowering,
but it seems like a lot of work to introduce pseudo-instructions, and
the current code seems to be reliable enough.
Fixes https://bugs.llvm.org/show_bug.cgi?id=42408.
Differential Revision: https://reviews.llvm.org/D63964
llvm-svn: 364970
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 18 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMMachineFunctionInfo.h | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/Thumb1FrameLowering.cpp | 8 |
3 files changed, 20 insertions, 8 deletions
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index d217cda4adc..e29077266fc 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -1071,7 +1071,6 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { const TargetRegisterInfo *TargetRegInfo = MF.getSubtarget().getRegisterInfo(); const MachineRegisterInfo &MachineRegInfo = MF.getRegInfo(); - const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>(); unsigned FramePtr = TargetRegInfo->getFrameRegister(MF); unsigned Opc = MI->getOpcode(); @@ -1135,7 +1134,12 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { Pad += Width; continue; } - RegList.push_back(MO.getReg()); + // Check for registers that are remapped (for a Thumb1 prologue that + // saves high registers). + unsigned Reg = MO.getReg(); + if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(Reg)) + Reg = RemappedReg; + RegList.push_back(Reg); } break; case ARM::STR_PRE_IMM: @@ -1185,7 +1189,7 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { unsigned CPI = MI->getOperand(1).getIndex(); const MachineConstantPool *MCP = MF.getConstantPool(); if (CPI >= MCP->getConstants().size()) - CPI = AFI.getOriginalCPIdx(CPI); + CPI = AFI->getOriginalCPIdx(CPI); assert(CPI != -1U && "Invalid constpool index"); // Derive the actual offset. @@ -1215,8 +1219,12 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { } else if (DstReg == ARM::SP) { MI->print(errs()); llvm_unreachable("Unsupported opcode for unwinding information"); - } - else { + } else if (Opc == ARM::tMOVr) { + // If a Thumb1 function spills r8-r11, we copy the values to low + // registers before pushing them. Record the copy so we can emit the + // correct ".save" later. + AFI->EHPrologueRemappedRegs[DstReg] = SrcReg; + } else { MI->print(errs()); llvm_unreachable("Unsupported opcode for unwinding information"); } diff --git a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h index f96124e10f3..90d794cd27b 100644 --- a/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h +++ b/llvm/lib/Target/ARM/ARMMachineFunctionInfo.h @@ -245,6 +245,8 @@ public: void setPromotedConstpoolIncrease(int Sz) { PromotedGlobalsIncrease = Sz; } + + DenseMap<unsigned, unsigned> EHPrologueRemappedRegs; }; } // end namespace llvm diff --git a/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp b/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp index 1b32df2104a..426e9a0ed9b 100644 --- a/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp +++ b/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp @@ -889,8 +889,9 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB, findNextOrderedReg(std::begin(AllCopyRegs), CopyRegs, AllCopyRegsEnd); // Create the PUSH, but don't insert it yet (the MOVs need to come first). - MachineInstrBuilder PushMIB = - BuildMI(MF, DL, TII.get(ARM::tPUSH)).add(predOps(ARMCC::AL)); + MachineInstrBuilder PushMIB = BuildMI(MF, DL, TII.get(ARM::tPUSH)) + .add(predOps(ARMCC::AL)) + .setMIFlags(MachineInstr::FrameSetup); SmallVector<unsigned, 4> RegsToPush; while (HiRegToSave != AllHighRegsEnd && CopyReg != AllCopyRegsEnd) { @@ -903,7 +904,8 @@ spillCalleeSavedRegisters(MachineBasicBlock &MBB, BuildMI(MBB, MI, DL, TII.get(ARM::tMOVr)) .addReg(*CopyReg, RegState::Define) .addReg(*HiRegToSave, getKillRegState(isKill)) - .add(predOps(ARMCC::AL)); + .add(predOps(ARMCC::AL)) + .setMIFlags(MachineInstr::FrameSetup); // Record the register that must be added to the PUSH. RegsToPush.push_back(*CopyReg); |

