[WinEH] Insert the catchpad return before CSR restoration
x64 catchpads use rax to inform the unwinder where control should go
next. However, we must initialize rax before the epilogue sequence so
as to not perturb the unwinder.
llvm-svn: 249910
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index f63be63..9d20fd7c 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -1058,6 +1058,7 @@
bool NeedsWinCFI =
IsWin64Prologue && MF.getFunction()->needsUnwindTableEntry();
bool IsFunclet = isFuncletReturnInstr(MBBI);
+ MachineBasicBlock *RestoreMBB = nullptr;
// Get the number of bytes to allocate from the FrameInfo.
uint64_t StackSize = MFI->getStackSize();
@@ -1082,7 +1083,7 @@
}
// For 32-bit, create a new block for the restore code.
- MachineBasicBlock *RestoreMBB = TargetMBB;
+ RestoreMBB = TargetMBB;
if (STI.is32Bit()) {
RestoreMBB = MF.CreateMachineBasicBlock(MBB.getBasicBlock());
MF.insert(TargetMBB, RestoreMBB);
@@ -1092,23 +1093,6 @@
MBBI->getOperand(0).setMBB(RestoreMBB);
}
- // Fill EAX/RAX with the address of the target block.
- unsigned ReturnReg = STI.is64Bit() ? X86::RAX : X86::EAX;
- if (STI.is64Bit()) {
- // LEA64r RestoreMBB(%rip), %rax
- BuildMI(MBB, MBBI, DL, TII.get(X86::LEA64r), ReturnReg)
- .addReg(X86::RIP)
- .addImm(0)
- .addReg(0)
- .addMBB(RestoreMBB)
- .addReg(0);
- } else {
- // MOV32ri $RestoreMBB, %eax
- BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri))
- .addReg(ReturnReg)
- .addMBB(RestoreMBB);
- }
-
// Pop EBP.
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
MachineFramePtr)
@@ -1161,6 +1145,25 @@
}
MachineBasicBlock::iterator FirstCSPop = MBBI;
+ if (RestoreMBB) {
+ // Fill EAX/RAX with the address of the target block.
+ unsigned ReturnReg = STI.is64Bit() ? X86::RAX : X86::EAX;
+ if (STI.is64Bit()) {
+ // LEA64r RestoreMBB(%rip), %rax
+ BuildMI(MBB, FirstCSPop, DL, TII.get(X86::LEA64r), ReturnReg)
+ .addReg(X86::RIP)
+ .addImm(0)
+ .addReg(0)
+ .addMBB(RestoreMBB)
+ .addReg(0);
+ } else {
+ // MOV32ri $RestoreMBB, %eax
+ BuildMI(MBB, FirstCSPop, DL, TII.get(X86::MOV32ri))
+ .addReg(ReturnReg)
+ .addMBB(RestoreMBB);
+ }
+ }
+
if (MBBI != MBB.end())
DL = MBBI->getDebugLoc();