summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-11-09 23:07:48 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-11-09 23:07:48 +0000
commitc30d240fb899bd0ad8295642447f6d48421113d1 (patch)
tree5a8e1606b124b7c1a6363eb7ebab3cbe32a0da0b
parent5d899048588e74cfed7aeb661f0b83eb8c2cab88 (diff)
[WinEH] Don't emit CATCHRET from visitCatchPad
Instead, emit a CATCHPAD node which will get selected to a target specific sequence. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252528 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h3
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td5
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp17
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp28
-rw-r--r--lib/Target/X86/X86ISelLowering.h3
-rw-r--r--lib/Target/X86/X86InstrCompiler.td6
-rw-r--r--test/CodeGen/X86/seh-catch-all.ll1
-rw-r--r--test/CodeGen/X86/seh-catchpad.ll10
-rw-r--r--test/CodeGen/X86/seh-exception-code.ll2
-rw-r--r--test/CodeGen/X86/win32-seh-catchpad-realign.ll6
-rw-r--r--test/CodeGen/X86/win32-seh-catchpad.ll1
11 files changed, 47 insertions, 35 deletions
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index c28802c34b2..4ca73914b72 100644
--- a/include/llvm/CodeGen/ISDOpcodes.h
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -591,6 +591,9 @@ namespace ISD {
/// take a chain as input and return a chain.
EH_LABEL,
+ /// CATCHPAD - Represents a catchpad instruction.
+ CATCHPAD,
+
/// CATCHRET - Represents a return from a catch block funclet. Used for
/// MSVC compatible exception handling. Takes a chain operand and a
/// destination basic block operand.
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index 7a73a0ff6b4..d83311f22fe 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -455,8 +455,11 @@ def brcc : SDNode<"ISD::BR_CC" , SDTBrCC, [SDNPHasChain]>;
def brcond : SDNode<"ISD::BRCOND" , SDTBrcond, [SDNPHasChain]>;
def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>;
def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>;
-def catchret : SDNode<"ISD::CATCHRET" , SDTCatchret, [SDNPHasChain]>;
+def catchret : SDNode<"ISD::CATCHRET" , SDTCatchret,
+ [SDNPHasChain, SDNPSideEffect]>;
def cleanupret : SDNode<"ISD::CLEANUPRET" , SDTNone, [SDNPHasChain]>;
+def catchpad : SDNode<"ISD::CATCHPAD" , SDTNone,
+ [SDNPHasChain, SDNPSideEffect]>;
def trap : SDNode<"ISD::TRAP" , SDTNone,
[SDNPHasChain, SDNPSideEffect]>;
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 60b06b4ab0e..5090bfbfb14 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -1178,7 +1178,6 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
void SelectionDAGBuilder::visitCatchPad(const CatchPadInst &I) {
auto Pers = classifyEHPersonality(FuncInfo.Fn->getPersonalityFn());
bool IsMSVCCXX = Pers == EHPersonality::MSVC_CXX;
- bool IsSEH = isAsynchronousEHPersonality(Pers);
bool IsCoreCLR = Pers == EHPersonality::CoreCLR;
MachineBasicBlock *CatchPadMBB = FuncInfo.MBB;
// In MSVC C++ and CoreCLR, catchblocks are funclets and need prologues.
@@ -1190,22 +1189,16 @@ void SelectionDAGBuilder::visitCatchPad(const CatchPadInst &I) {
// Update machine-CFG edge.
FuncInfo.MBB->addSuccessor(NormalDestMBB);
- // CatchPads in SEH are not funclets, they are merely markers which indicate
- // where to insert register restoration code.
- if (IsSEH) {
- DAG.setRoot(DAG.getNode(ISD::CATCHRET, getCurSDLoc(), MVT::Other,
- getControlRoot(), DAG.getBasicBlock(NormalDestMBB),
- DAG.getBasicBlock(&FuncInfo.MF->front())));
- return;
- }
+ SDValue Chain =
+ DAG.getNode(ISD::CATCHPAD, getCurSDLoc(), MVT::Other, getControlRoot());
// If this is not a fall-through branch or optimizations are switched off,
// emit the branch.
if (NormalDestMBB != NextBlock(CatchPadMBB) ||
TM.getOptLevel() == CodeGenOpt::None)
- DAG.setRoot(DAG.getNode(ISD::BR, getCurSDLoc(), MVT::Other,
- getControlRoot(),
- DAG.getBasicBlock(NormalDestMBB)));
+ Chain = DAG.getNode(ISD::BR, getCurSDLoc(), MVT::Other, Chain,
+ DAG.getBasicBlock(NormalDestMBB));
+ DAG.setRoot(Chain);
}
void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) {
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 8d7712d3cd0..f5b38b39696 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -21401,15 +21401,7 @@ X86TargetLowering::EmitLoweredCatchRet(MachineInstr *MI,
MachineBasicBlock *TargetMBB = MI->getOperand(0).getMBB();
DebugLoc DL = MI->getDebugLoc();
- // SEH does not outline catch bodies into funclets. Turn CATCHRETs into
- // JMP_4s, possibly with some extra restoration code for 32-bit EH.
- if (IsSEH) {
- if (Subtarget->is32Bit())
- BuildMI(*BB, MI, DL, TII.get(X86::EH_RESTORE));
- BuildMI(*BB, MI, DL, TII.get(X86::JMP_4)).addMBB(TargetMBB);
- MI->eraseFromParent();
- return BB;
- }
+ assert(!IsSEH && "SEH does not use catchret!");
// Only 32-bit EH needs to worry about manually restoring stack pointers.
if (!Subtarget->is32Bit())
@@ -21432,6 +21424,22 @@ X86TargetLowering::EmitLoweredCatchRet(MachineInstr *MI,
}
MachineBasicBlock *
+X86TargetLowering::EmitLoweredCatchPad(MachineInstr *MI,
+ MachineBasicBlock *BB) const {
+ MachineFunction *MF = BB->getParent();
+ const Constant *PerFn = MF->getFunction()->getPersonalityFn();
+ bool IsSEH = isAsynchronousEHPersonality(classifyEHPersonality(PerFn));
+ // Only 32-bit SEH requires special handling for catchpad.
+ if (IsSEH && Subtarget->is32Bit()) {
+ const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
+ DebugLoc DL = MI->getDebugLoc();
+ BuildMI(*BB, MI, DL, TII.get(X86::EH_RESTORE));
+ }
+ MI->eraseFromParent();
+ return BB;
+}
+
+MachineBasicBlock *
X86TargetLowering::EmitLoweredTLSCall(MachineInstr *MI,
MachineBasicBlock *BB) const {
// This is pretty easy. We're taking the value that we received from
@@ -21813,6 +21821,8 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
return EmitLoweredWinAlloca(MI, BB);
case X86::CATCHRET:
return EmitLoweredCatchRet(MI, BB);
+ case X86::CATCHPAD:
+ return EmitLoweredCatchPad(MI, BB);
case X86::SEG_ALLOCA_32:
case X86::SEG_ALLOCA_64:
return EmitLoweredSegAlloca(MI, BB);
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index e7dbaa995c8..c800f16489b 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -1101,6 +1101,9 @@ namespace llvm {
MachineBasicBlock *EmitLoweredCatchRet(MachineInstr *MI,
MachineBasicBlock *BB) const;
+ MachineBasicBlock *EmitLoweredCatchPad(MachineInstr *MI,
+ MachineBasicBlock *BB) const;
+
MachineBasicBlock *EmitLoweredSegAlloca(MachineInstr *MI,
MachineBasicBlock *BB) const;
diff --git a/lib/Target/X86/X86InstrCompiler.td b/lib/Target/X86/X86InstrCompiler.td
index f35fd5c1388..e6141ade92b 100644
--- a/lib/Target/X86/X86InstrCompiler.td
+++ b/lib/Target/X86/X86InstrCompiler.td
@@ -156,13 +156,17 @@ let isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1,
isCodeGenOnly = 1, isReturn = 1 in {
def CLEANUPRET : I<0, Pseudo, (outs), (ins), "# CLEANUPRET", [(cleanupret)]>;
- // CATCHRET needs a custom inserter for SEH nonsense.
+ // CATCHRET needs a custom inserter for SEH.
let usesCustomInserter = 1 in
def CATCHRET : I<0, Pseudo, (outs), (ins brtarget32:$dst, brtarget32:$from),
"# CATCHRET",
[(catchret bb:$dst, bb:$from)]>;
}
+let hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1, isCodeGenOnly = 1,
+ usesCustomInserter = 1 in
+def CATCHPAD : I<0, Pseudo, (outs), (ins), "# CATCHPAD", [(catchpad)]>;
+
// This instruction is responsible for re-establishing stack pointers after an
// exception has been caught and we are rejoining normal control flow in the
// parent function or funclet. It generally sets ESP and EBP, and optionally
diff --git a/test/CodeGen/X86/seh-catch-all.ll b/test/CodeGen/X86/seh-catch-all.ll
index 0c4f33f6300..aa1b6e040ff 100644
--- a/test/CodeGen/X86/seh-catch-all.ll
+++ b/test/CodeGen/X86/seh-catch-all.ll
@@ -34,7 +34,6 @@ endpad:
; CHECK: callq crash
; CHECK: retq
; CHECK: .LBB0_2: # %lpad
-; CHECK: # %catchall
; CHECK: leaq str(%rip), %rcx
; CHECK: movl %eax, %edx
; CHECK: callq printf
diff --git a/test/CodeGen/X86/seh-catchpad.ll b/test/CodeGen/X86/seh-catchpad.ll
index b59aa8d4c78..93775b6aada 100644
--- a/test/CodeGen/X86/seh-catchpad.ll
+++ b/test/CodeGen/X86/seh-catchpad.ll
@@ -121,8 +121,6 @@ ehcleanup.end: ; preds = %ehcleanup
; CHECK: callq "?fin$0@0@main@@"
; CHECK: jmp .LBB1_[[epilogue]]
; CHECK: .LBB1_[[except2bb:[0-9]+]]: # %catch.dispatch.7
-; CHECK: jmp .LBB1_7
-; CHECK: # %__except.9
; CHECK: leaq "??_C@_06IBDBCMGJ@caught?$AA@"(%rip), %rcx
; CHECK: callq puts
; CHECK: jmp .LBB1_[[epilogue]]
@@ -145,18 +143,18 @@ ehcleanup.end: ; preds = %ehcleanup
; CHECK-NEXT: .long .Ltmp2@IMGREL+1
; CHECK-NEXT: .long .Ltmp3@IMGREL+1
; CHECK-NEXT: .long "?filt$0@0@main@@"@IMGREL
-; CHECK-NEXT: .long .LBB1_6@IMGREL
+; CHECK-NEXT: .long .LBB1_5@IMGREL
; CHECK-NEXT: .long .Ltmp6@IMGREL+1
; CHECK-NEXT: .long .Ltmp7@IMGREL+1
; CHECK-NEXT: .long "?filt$0@0@main@@"@IMGREL
-; CHECK-NEXT: .long .LBB1_6@IMGREL
+; CHECK-NEXT: .long .LBB1_5@IMGREL
; CHECK-NEXT: .Llsda_end0:
; CHECK: .text
; CHECK: .seh_endproc
-; CHECK: "?dtor$4@?0?main@4HA":
-; CHECK: .seh_proc "?dtor$4@?0?main@4HA"
+; CHECK: "?dtor$3@?0?main@4HA":
+; CHECK: .seh_proc "?dtor$3@?0?main@4HA"
; CHECK: .seh_handler __C_specific_handler, @unwind, @except
; CHECK: .LBB1_[[finbb]]: # %ehcleanup
; CHECK: movq %rdx, 16(%rsp)
diff --git a/test/CodeGen/X86/seh-exception-code.ll b/test/CodeGen/X86/seh-exception-code.ll
index 3a314553ca1..e481a8e308c 100644
--- a/test/CodeGen/X86/seh-exception-code.ll
+++ b/test/CodeGen/X86/seh-exception-code.ll
@@ -36,6 +36,6 @@ catchendblock: ; preds = %catch.dispatch
; CHECK: xorl %ecx, %ecx
; CHECK: callq f
-; CHECK: # %__except
+; CHECK: # %catch.dispatch
; CHECK: movl %eax, %ecx
; CHECK-NEXT: callq f
diff --git a/test/CodeGen/X86/win32-seh-catchpad-realign.ll b/test/CodeGen/X86/win32-seh-catchpad-realign.ll
index 9cc9118965c..24db1649eb8 100644
--- a/test/CodeGen/X86/win32-seh-catchpad-realign.ll
+++ b/test/CodeGen/X86/win32-seh-catchpad-realign.ll
@@ -61,7 +61,7 @@ declare i32 @_except_handler3(...)
; CHECK: calll _useit
;
; Epilogue
-; CHECK: LBB0_1: # %__try.cont
+; CHECK: LBB0_2: # %__try.cont
; CHECK: leal -12(%ebp), %esp
; CHECK: popl %esi
; CHECK: popl %edi
@@ -69,7 +69,7 @@ declare i32 @_except_handler3(...)
; CHECK: popl %ebp
; CHECK: retl
;
-; CHECK: LBB0_2: # %catch.dispatch
+; CHECK: LBB0_1: # %catch.dispatch
; Restore ESP
; CHECK: movl -24(%ebp), %esp
; Recompute ESI by subtracting 60 from the end of the registration node.
@@ -77,4 +77,4 @@ declare i32 @_except_handler3(...)
; Restore EBP
; CHECK: movl 12(%esi), %ebp
; Rejoin normal control flow
-; CHECK: jmp LBB0_1
+; CHECK: jmp LBB0_2
diff --git a/test/CodeGen/X86/win32-seh-catchpad.ll b/test/CodeGen/X86/win32-seh-catchpad.ll
index dd14f2df689..4e373af23e4 100644
--- a/test/CodeGen/X86/win32-seh-catchpad.ll
+++ b/test/CodeGen/X86/win32-seh-catchpad.ll
@@ -220,7 +220,6 @@ catchendblock: ; preds = %catch.dispatch
; CHECK: # %catch.dispatch
; CHECK-NEXT: movl -24(%ebp), %esp
; CHECK-NEXT: addl $12, %ebp
-; CHECK: # %__except.ret
; CHECK-NEXT: movl $-1, -16(%ebp)
; CHECK-NEXT: movl $2, (%esp)
; CHECK-NEXT: calll _f