Fix failure to invoke exception handler on Win64
[oota-llvm.git] / lib / Target / X86 / X86MCInstLower.cpp
index 2471667d95bbf9c104d137506a567ee080f61f83..7f0af3e581acbc8e093cca5fe8abfe437e58a9b9 100644 (file)
@@ -826,6 +826,20 @@ void X86AsmPrinter::LowerPATCHPOINT(const MachineInstr &MI) {
            getSubtargetInfo());
 }
 
+// Returns instruction preceding MBBI in MachineFunction.
+// If MBBI is the first instruction of the first basic block, returns null.
+static MachineBasicBlock::const_iterator
+PrevCrossBBInst(MachineBasicBlock::const_iterator MBBI) {
+  const MachineBasicBlock *MBB = MBBI->getParent();
+  while (MBBI == MBB->begin()) {
+    if (MBB == MBB->getParent()->begin())
+      return nullptr;
+    MBB = MBB->getPrevNode();
+    MBBI = MBB->end();
+  }
+  return --MBBI;
+}
+
 void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
   X86MCInstLower MCInstLowering(*MF, *this);
   const X86RegisterInfo *RI =
@@ -967,6 +981,21 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
     OutStreamer.EmitWinCFIEndProlog();
     return;
 
+  case X86::SEH_Epilogue: {
+    MachineBasicBlock::const_iterator MBBI(MI);
+    // Check if preceded by a call and emit nop if so.
+    for (MBBI = PrevCrossBBInst(MBBI); MBBI; MBBI = PrevCrossBBInst(MBBI)) {
+      // Conservatively assume that pseudo instructions don't emit code and keep
+      // looking for a call. We may emit an unnecessary nop in some cases.
+      if (!MBBI->isPseudo()) {
+        if (MBBI->isCall())
+          EmitAndCountInstruction(MCInstBuilder(X86::NOOP));
+        break;
+      }
+    }
+    return;
+  }
+
   case X86::PSHUFBrm:
   case X86::VPSHUFBrm:
     // Lower PSHUFB normally but add a comment if we can find a constant