Revert "Revert "Revert r248959, "[WinEH] Emit int3 after noreturn calls on Win64"""

This reverts commit r249794.

Apparently my checkouts are full of unexpected surprises today.

llvm-svn: 249796
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index f97edb4..13b097c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1569,8 +1569,10 @@
   }
 
   case Instruction::Unreachable:
-    // Nothing to emit.
-    return true;
+    if (TM.Options.TrapUnreachable)
+      return fastEmit_(MVT::Other, MVT::Other, ISD::TRAP) != 0;
+    else
+      return true;
 
   case Instruction::Alloca:
     // FunctionLowering has the static-sized case covered.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 9371944..9e31519 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2260,7 +2260,11 @@
                           getValue(I.getAddress())));
 }
 
-void SelectionDAGBuilder::visitUnreachable(const UnreachableInst &I) {}
+void SelectionDAGBuilder::visitUnreachable(const UnreachableInst &I) {
+  if (DAG.getTarget().Options.TrapUnreachable)
+    DAG.setRoot(
+        DAG.getNode(ISD::TRAP, getCurSDLoc(), MVT::Other, DAG.getRoot()));
+}
 
 void SelectionDAGBuilder::visitFSub(const User &I) {
   // -0.0 - X --> fneg
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 9954b6c..fae877a 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -2951,20 +2951,6 @@
   return DAG.getVectorShuffle(VT, dl, V1, V2, &Mask[0]);
 }
 
-/// Check if the fall through instruction after a call site is unreachable.
-/// FIXME: This will fail if there are interesting non-code generating IR
-/// instructions between the call and the unreachable (lifetime.end). In
-/// practice, this should be rare because optimizations like to delete non-call
-/// code before unreachable.
-static bool isCallFollowedByUnreachable(ImmutableCallSite CS) {
-  const Instruction *NextInst;
-  if (auto *II = dyn_cast<InvokeInst>(CS.getInstruction()))
-    NextInst = II->getNormalDest()->getFirstNonPHIOrDbg();
-  else
-    NextInst = CS.getInstruction()->getNextNode();
-  return isa<UnreachableInst>(NextInst);
-}
-
 SDValue
 X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
                              SmallVectorImpl<SDValue> &InVals) const {
@@ -3470,15 +3456,6 @@
     InFlag = Chain.getValue(1);
   }
 
-  if (Subtarget->isTargetWin64() && CLI.CS) {
-    // Look for a call followed by unreachable. On Win64, we need to ensure that
-    // the call does not accidentally fall through to something that looks like
-    // an epilogue. We do this by inserting a DEBUGTRAP, which lowers to int3,
-    // which is what MSVC emits after noreturn calls.
-    if (isCallFollowedByUnreachable(*CLI.CS))
-      Chain = DAG.getNode(ISD::DEBUGTRAP, dl, MVT::Other, Chain);
-  }
-
   // Handle result values, copying them out of physregs into vregs that we
   // return.
   return LowerCallResult(Chain, InFlag, CallConv, isVarArg,
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index d318244..2e869eb 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -110,6 +110,13 @@
                         OL),
       TLOF(createTLOF(getTargetTriple())),
       Subtarget(TT, CPU, FS, *this, Options.StackAlignmentOverride) {
+  // Windows stack unwinder gets confused when execution flow "falls through"
+  // after a call to 'noreturn' function.
+  // To prevent that, we emit a trap for 'unreachable' IR instructions.
+  // (which on X86, happens to be the 'ud2' instruction)
+  if (Subtarget.isTargetWin64())
+    this->Options.TrapUnreachable = true;
+
   // By default (and when -ffast-math is on), enable estimate codegen for
   // everything except scalar division. By default, use 1 refinement step for
   // all operations. Defaults may be overridden by using command-line options.