[llvm] r248839 - [WinEH] Ensure that funclets obey the x64 ABI

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 15:33:37 PDT 2015


Author: majnemer
Date: Tue Sep 29 17:33:36 2015
New Revision: 248839

URL: http://llvm.org/viewvc/llvm-project?rev=248839&view=rev
Log:
[WinEH] Ensure that funclets obey the x64 ABI

The x64 ABI requires that epilogues do not contain code other than stack
adjustments and some limited control flow.  However, we'd insert code to
initialize the return address after stack adjustments.  Instead, insert
EAX/RAX with the current value before we create the stack adjustments in
the epilogue.

Modified:
    llvm/trunk/lib/Target/X86/X86ExpandPseudo.cpp
    llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
    llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll
    llvm/trunk/test/CodeGen/X86/win-catchpad.ll
    llvm/trunk/test/CodeGen/X86/win-funclet-cfi.ll

Modified: llvm/trunk/lib/Target/X86/X86ExpandPseudo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ExpandPseudo.cpp?rev=248839&r1=248838&r2=248839&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ExpandPseudo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ExpandPseudo.cpp Tue Sep 29 17:33:36 2015
@@ -141,41 +141,6 @@ bool X86ExpandPseudo::ExpandMI(MachineBa
     // The EH_RETURN pseudo is really removed during the MC Lowering.
     return true;
   }
-
-  case X86::CLEANUPRET: {
-    // Replace CATCHRET with the appropriate RET.
-    unsigned RetOp = STI->is64Bit() ? X86::RETQ : X86::RETL;
-    BuildMI(MBB, MBBI, DL, TII->get(RetOp));
-    MBBI->eraseFromParent();
-    return true;
-  }
-
-  case X86::CATCHRET: {
-    MachineBasicBlock *TargetMBB = MBBI->getOperand(0).getMBB();
-
-    // Fill EAX/RAX with the address of the target block.
-    unsigned ReturnReg = STI->is64Bit() ? X86::RAX : X86::EAX;
-    unsigned RetOp = STI->is64Bit() ? X86::RETQ : X86::RETL;
-    if (STI->is64Bit()) {
-      // LEA64r TargetMBB(%rip), %rax
-      BuildMI(MBB, MBBI, DL, TII->get(X86::LEA64r), ReturnReg)
-          .addReg(X86::RIP)
-          .addImm(0)
-          .addReg(0)
-          .addMBB(TargetMBB)
-          .addReg(0);
-    } else {
-      // MOV32ri $TargetMBB, %eax
-      BuildMI(MBB, MBBI, DL, TII->get(X86::MOV32ri))
-          .addReg(ReturnReg)
-          .addMBB(TargetMBB);
-    }
-
-    // Replace CATCHRET with the appropriate RET.
-    BuildMI(MBB, MBBI, DL, TII->get(RetOp)).addReg(ReturnReg);
-    MBBI->eraseFromParent();
-    return true;
-  }
   }
   llvm_unreachable("Previous switch has a fallthrough?");
 }

Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.cpp?rev=248839&r1=248838&r2=248839&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp Tue Sep 29 17:33:36 2015
@@ -1093,9 +1093,26 @@ void X86FrameLowering::emitEpilogue(Mach
     if (STI.is32Bit()) {
       RestoreMBB = MF.CreateMachineBasicBlock(MBB.getBasicBlock());
       MF.insert(TargetMBB, RestoreMBB);
-      MBB.transferSuccessors(RestoreMBB);
+      MBB.removeSuccessor(TargetMBB);
       MBB.addSuccessor(RestoreMBB);
-      MBBI->getOperand(0).setMBB(RestoreMBB);
+      RestoreMBB->addSuccessor(TargetMBB);
+    }
+
+    // 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.
@@ -1111,12 +1128,24 @@ void X86FrameLowering::emitEpilogue(Mach
       BuildMI(*RestoreMBB, RestoreMBBI, DL, TII.get(X86::JMP_4))
           .addMBB(TargetMBB);
     }
-  } else if (isFuncletReturnInstr(MBBI)) {
+    // Replace CATCHRET with the appropriate RET.
+    unsigned RetOp = STI.is64Bit() ? X86::RETQ : X86::RETL;
+    MachineBasicBlock::iterator NewExit =
+        BuildMI(MBB, MBBI, DL, TII.get(RetOp)).addReg(ReturnReg);
+    MBBI->eraseFromParent();
+    MBBI = NewExit;
+  } else if (MBBI->getOpcode() == X86::CLEANUPRET) {
     NumBytes = MFI->getMaxCallFrameSize();
     assert(hasFP(MF) && "EH funclets without FP not yet implemented");
     BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
             MachineFramePtr)
         .setMIFlag(MachineInstr::FrameDestroy);
+    // Replace CLEANUPRET with the appropriate RET.
+    unsigned RetOp = STI.is64Bit() ? X86::RETQ : X86::RETL;
+    MachineBasicBlock::iterator NewExit =
+        BuildMI(MBB, MBBI, DL, TII.get(RetOp));
+    MBBI->eraseFromParent();
+    MBBI = NewExit;
   } else if (hasFP(MF)) {
     // Calculate required stack adjustment.
     uint64_t FrameSize = StackSize - SlotSize;

Modified: llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll?rev=248839&r1=248838&r2=248839&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win-catchpad-csrs.ll Tue Sep 29 17:33:36 2015
@@ -80,9 +80,9 @@ catchendblock:
 ; X86: movl $1, -{{[0-9]+}}(%ebp)
 ; X86: movl $2, (%esp)
 ; X86: calll _f
-; X86: addl $16, %esp
+; X86: movl $[[restorebb]], %eax
+; X86-NEXT: addl $16, %esp
 ; X86-NEXT: popl %ebp
-; X86-NEXT: movl $[[restorebb]], %eax
 ; X86-NEXT: retl
 
 ; X86: L__ehtable$try_catch_catch:
@@ -125,9 +125,9 @@ catchendblock:
 ; X64: subq $32, %rsp
 ; X64: movl $2, %ecx
 ; X64: callq f
+; X64: leaq [[contbb]](%rip), %rax
 ; X64: addq $32, %rsp
 ; X64: popq %rbp
-; X64: leaq [[contbb]](%rip), %rax
 ; X64: retq
 
 ; X64: $handlerMap$0$try_catch_catch:

Modified: llvm/trunk/test/CodeGen/X86/win-catchpad.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win-catchpad.ll?rev=248839&r1=248838&r2=248839&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win-catchpad.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win-catchpad.ll Tue Sep 29 17:33:36 2015
@@ -73,7 +73,13 @@ catchendblock:
 ; X86: [[contbb:LBB0_[0-9]+]]: # %try.cont
 ; X86: retl
 
-; X86: [[restorebb:LBB0_[0-9]+]]: # %invoke.cont.3
+; FIXME: These should be de-duplicated.
+; X86: [[restorebb1:LBB0_[0-9]+]]: # %invoke.cont.2
+; X86: movl -16(%ebp), %esp
+; X86: addl $12, %ebp
+; X86: jmp [[contbb]]
+
+; X86: [[restorebb2:LBB0_[0-9]+]]: # %invoke.cont.3
 ; X86: movl -16(%ebp), %esp
 ; X86: addl $12, %ebp
 ; X86: jmp [[contbb]]
@@ -89,9 +95,9 @@ catchendblock:
 ; X86-DAG: movl %[[addr_reg]], 4(%esp)
 ; X86-DAG: movl %[[e_reg]], (%esp)
 ; X86: calll _f
+; X86-NEXT: movl $[[restorebb1]], %eax
 ; X86-NEXT: addl $8, %esp
 ; X86-NEXT: popl %ebp
-; X86-NEXT: movl $[[restorebb]], %eax
 ; X86-NEXT: retl
 
 ; X86: "?catch$[[catch2bb:[0-9]+]]@?0?try_catch_catch at 4HA":
@@ -104,9 +110,9 @@ catchendblock:
 ; X86-DAG: movl %[[addr_reg]], 4(%esp)
 ; X86-DAG: movl $3, (%esp)
 ; X86: calll _f
+; X86-NEXT: movl $[[restorebb2]], %eax
 ; X86-NEXT: addl $8, %esp
 ; X86-NEXT: popl %ebp
-; X86-NEXT: movl $[[restorebb]], %eax
 ; X86-NEXT: retl
 
 ; X86: L__ehtable$try_catch_catch:
@@ -147,9 +153,9 @@ catchendblock:
 ; X64-DAG: leaq -[[local_offs]](%rbp), %rdx
 ; X64-DAG: movl [[e_addr:[-0-9]+]](%rbp), %ecx
 ; X64: callq f
-; X64: addq $32, %rsp
+; X64: leaq [[contbb]](%rip), %rax
+; X64-NEXT: addq $32, %rsp
 ; X64-NEXT: popq %rbp
-; X64-NEXT: leaq [[contbb]](%rip), %rax
 ; X64-NEXT: retq
 
 ; X64: "?catch$[[catch2bb:[0-9]+]]@?0?try_catch_catch at 4HA":
@@ -162,9 +168,9 @@ catchendblock:
 ; X64-DAG: movl $3, %ecx
 ; X64: callq f
 ; X64: .Ltmp3
-; X64: addq $32, %rsp
+; X64: leaq [[contbb]](%rip), %rax
+; X64-NEXT: addq $32, %rsp
 ; X64-NEXT: popq %rbp
-; X64-NEXT: leaq [[contbb]](%rip), %rax
 ; X64-NEXT: retq
 
 ; X64: $cppxdata$try_catch_catch:

Modified: llvm/trunk/test/CodeGen/X86/win-funclet-cfi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/win-funclet-cfi.ll?rev=248839&r1=248838&r2=248839&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/win-funclet-cfi.ll (original)
+++ llvm/trunk/test/CodeGen/X86/win-funclet-cfi.ll Tue Sep 29 17:33:36 2015
@@ -89,9 +89,9 @@ declare i32 @__CxxFrameHandler3(...)
 ; Prologue is done, emit the .seh_endprologue directive.
 ; CHECK: .seh_endprologue
 
-; Make sure there is a nop after a call if the call precedes the epilogue.
+; Make sure there is at least one instruction after a call before the epilogue.
 ; CHECK: callq g
-; CHECK-NEXT: nop
+; CHECK-NEXT: leaq    .LBB0_{{[0-9]+}}(%rip), %rax
 
 ; Emit a reference to the LSDA.
 ; CHECK: .seh_handlerdata




More information about the llvm-commits mailing list