summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2015-10-09 01:13:17 +0000
committerReid Kleckner <rnk@google.com>2015-10-09 01:13:17 +0000
commitae44e871cdd5c51a17198733e9b795d2eabaef14 (patch)
tree06987cd62dd9dcf85520edcf012ec34ddeea4800 /llvm/lib
parent37bb6810f24a68643aea0268b85e7c1b9f1a3f02 (diff)
downloadbcm5719-llvm-ae44e871cdd5c51a17198733e9b795d2eabaef14.tar.gz
bcm5719-llvm-ae44e871cdd5c51a17198733e9b795d2eabaef14.zip
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
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/FastISel.cpp6
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp6
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp23
-rw-r--r--llvm/lib/Target/X86/X86TargetMachine.cpp7
4 files changed, 16 insertions, 26 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index f97edb4ef09..13b097cfc60 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -1569,8 +1569,10 @@ bool FastISel::selectOperator(const User *I, unsigned Opcode) {
}
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 9371944d242..9e315194c98 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2260,7 +2260,11 @@ void SelectionDAGBuilder::visitIndirectBr(const IndirectBrInst &I) {
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 9954b6c63ce..fae877ab222 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -2951,20 +2951,6 @@ static SDValue getMOVL(SelectionDAG &DAG, SDLoc dl, EVT VT, SDValue V1,
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 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
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 d318244e0f7..2e869eb7c3c 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -110,6 +110,13 @@ X86TargetMachine::X86TargetMachine(const Target &T, const Triple &TT,
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.
OpenPOWER on IntegriCloud