[WinEH] Insert the catchpad return before CSR restoration
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 9 Oct 2015 22:18:45 +0000 (22:18 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 9 Oct 2015 22:18:45 +0000 (22:18 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249910 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86FrameLowering.cpp
test/CodeGen/X86/win-catchpad-csrs.ll

index f63be63..9d20fd7 100644 (file)
@@ -1058,6 +1058,7 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
   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 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
     }
 
     // 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 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
       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 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
   }
   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();
 
index 05a59ac..5e8c335 100644 (file)
@@ -123,6 +123,8 @@ catchendblock:                                    ; preds = %catch,
 ; X64: movq %rdx, 16(%rsp)
 ; X64: pushq %rbp
 ; X64: .seh_pushreg 5
+; X64: pushq %rsi
+; X64: .seh_pushreg 6
 ; X64: subq $32, %rsp
 ; X64: .seh_stackalloc 32
 ; X64: leaq 32(%rdx), %rbp
@@ -131,6 +133,7 @@ catchendblock:                                    ; preds = %catch,
 ; X64: callq f
 ; X64: leaq [[contbb]](%rip), %rax
 ; X64: addq $32, %rsp
+; X64: popq %rsi
 ; X64: popq %rbp
 ; X64: retq