Re-commit "[SEH] Remove the old __C_specific_handler code now that WinEHPrepare works"
This reverts commit r235617. r235649 should have addressed the problems. llvm-svn: 235667
This commit is contained in:
parent
ef68056521
commit
5c5facc2ce
|
@ -77,7 +77,6 @@ struct LandingPadInfo {
|
||||||
MachineBasicBlock *LandingPadBlock; // Landing pad block.
|
MachineBasicBlock *LandingPadBlock; // Landing pad block.
|
||||||
SmallVector<MCSymbol *, 1> BeginLabels; // Labels prior to invoke.
|
SmallVector<MCSymbol *, 1> BeginLabels; // Labels prior to invoke.
|
||||||
SmallVector<MCSymbol *, 1> EndLabels; // Labels after invoke.
|
SmallVector<MCSymbol *, 1> EndLabels; // Labels after invoke.
|
||||||
SmallVector<MCSymbol *, 1> ClauseLabels; // Labels for each clause.
|
|
||||||
SmallVector<SEHHandler, 1> SEHHandlers; // SEH handlers active at this lpad.
|
SmallVector<SEHHandler, 1> SEHHandlers; // SEH handlers active at this lpad.
|
||||||
MCSymbol *LandingPadLabel; // Label at beginning of landing pad.
|
MCSymbol *LandingPadLabel; // Label at beginning of landing pad.
|
||||||
const Function *Personality; // Personality function.
|
const Function *Personality; // Personality function.
|
||||||
|
@ -361,11 +360,6 @@ public:
|
||||||
///
|
///
|
||||||
void addCleanup(MachineBasicBlock *LandingPad);
|
void addCleanup(MachineBasicBlock *LandingPad);
|
||||||
|
|
||||||
/// Add a clause for a landing pad. Returns a new label for the clause. This
|
|
||||||
/// is used by EH schemes that have more than one landing pad. In this case,
|
|
||||||
/// each clause gets its own basic block.
|
|
||||||
MCSymbol *addClauseForLandingPad(MachineBasicBlock *LandingPad);
|
|
||||||
|
|
||||||
void addSEHCatchHandler(MachineBasicBlock *LandingPad, const Function *Filter,
|
void addSEHCatchHandler(MachineBasicBlock *LandingPad, const Function *Filter,
|
||||||
const BlockAddress *RecoverLabel);
|
const BlockAddress *RecoverLabel);
|
||||||
|
|
||||||
|
|
|
@ -206,12 +206,6 @@ void Win64Exception::emitCSpecificHandlerTable() {
|
||||||
for (const CallSiteEntry &CSE : CallSites) {
|
for (const CallSiteEntry &CSE : CallSites) {
|
||||||
if (!CSE.LPad)
|
if (!CSE.LPad)
|
||||||
continue; // Ignore gaps.
|
continue; // Ignore gaps.
|
||||||
for (int Selector : CSE.LPad->TypeIds) {
|
|
||||||
// Ignore C++ filter clauses in SEH.
|
|
||||||
// FIXME: Implement cleanup clauses.
|
|
||||||
if (isCatchEHSelector(Selector))
|
|
||||||
++NumEntries;
|
|
||||||
}
|
|
||||||
NumEntries += CSE.LPad->SEHHandlers.size();
|
NumEntries += CSE.LPad->SEHHandlers.size();
|
||||||
}
|
}
|
||||||
Asm->OutStreamer.EmitIntValue(NumEntries, 4);
|
Asm->OutStreamer.EmitIntValue(NumEntries, 4);
|
||||||
|
@ -267,40 +261,6 @@ void Win64Exception::emitCSpecificHandlerTable() {
|
||||||
else
|
else
|
||||||
Asm->OutStreamer.EmitIntValue(0, 4);
|
Asm->OutStreamer.EmitIntValue(0, 4);
|
||||||
}
|
}
|
||||||
if (!LPad->SEHHandlers.empty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// These aren't really type info globals, they are actually pointers to
|
|
||||||
// filter functions ordered by selector. The zero selector is used for
|
|
||||||
// cleanups, so slot zero corresponds to selector 1.
|
|
||||||
const std::vector<const GlobalValue *> &SelectorToFilter = MMI->getTypeInfos();
|
|
||||||
|
|
||||||
// Do a parallel iteration across typeids and clause labels, skipping filter
|
|
||||||
// clauses.
|
|
||||||
size_t NextClauseLabel = 0;
|
|
||||||
for (size_t I = 0, E = LPad->TypeIds.size(); I < E; ++I) {
|
|
||||||
// AddLandingPadInfo stores the clauses in reverse, but there is a FIXME
|
|
||||||
// to change that.
|
|
||||||
int Selector = LPad->TypeIds[E - I - 1];
|
|
||||||
|
|
||||||
// Ignore C++ filter clauses in SEH.
|
|
||||||
// FIXME: Implement cleanup clauses.
|
|
||||||
if (!isCatchEHSelector(Selector))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Asm->OutStreamer.EmitValue(Begin, 4);
|
|
||||||
Asm->OutStreamer.EmitValue(End, 4);
|
|
||||||
if (isCatchEHSelector(Selector)) {
|
|
||||||
assert(unsigned(Selector - 1) < SelectorToFilter.size());
|
|
||||||
const GlobalValue *TI = SelectorToFilter[Selector - 1];
|
|
||||||
if (TI) // Emit the filter function pointer.
|
|
||||||
Asm->OutStreamer.EmitValue(createImageRel32(Asm->getSymbol(TI)), 4);
|
|
||||||
else // Otherwise, this is a "catch i8* null", or catch all.
|
|
||||||
Asm->OutStreamer.EmitIntValue(1, 4);
|
|
||||||
}
|
|
||||||
MCSymbol *ClauseLabel = LPad->ClauseLabels[NextClauseLabel++];
|
|
||||||
Asm->OutStreamer.EmitValue(createImageRel32(ClauseLabel), 4);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -461,14 +461,6 @@ void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) {
|
||||||
LP.TypeIds.push_back(0);
|
LP.TypeIds.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
MCSymbol *
|
|
||||||
MachineModuleInfo::addClauseForLandingPad(MachineBasicBlock *LandingPad) {
|
|
||||||
MCSymbol *ClauseLabel = Context.CreateTempSymbol();
|
|
||||||
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
|
||||||
LP.ClauseLabels.push_back(ClauseLabel);
|
|
||||||
return ClauseLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MachineModuleInfo::addSEHCatchHandler(MachineBasicBlock *LandingPad,
|
void MachineModuleInfo::addSEHCatchHandler(MachineBasicBlock *LandingPad,
|
||||||
const Function *Filter,
|
const Function *Filter,
|
||||||
const BlockAddress *RecoverBA) {
|
const BlockAddress *RecoverBA) {
|
||||||
|
|
|
@ -955,76 +955,20 @@ bool SelectionDAGISel::PrepareEHLandingPad() {
|
||||||
// Mark the clause as a landing pad or MI passes will delete it.
|
// Mark the clause as a landing pad or MI passes will delete it.
|
||||||
ClauseBB->setIsLandingPad();
|
ClauseBB->setIsLandingPad();
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Otherwise, we haven't done the preparation, and we need to invent some
|
|
||||||
// clause basic blocks that branch into the landingpad.
|
|
||||||
// FIXME: Remove this code once SEH preparation works.
|
|
||||||
ActionsCall = nullptr;
|
|
||||||
|
|
||||||
// Make virtual registers and a series of labels that fill in values for
|
|
||||||
// the clauses.
|
|
||||||
auto &RI = MF->getRegInfo();
|
|
||||||
FuncInfo->ExceptionSelectorVirtReg = RI.createVirtualRegister(PtrRC);
|
|
||||||
|
|
||||||
// Emit separate machine basic blocks with separate labels for each clause
|
|
||||||
// before the main landing pad block.
|
|
||||||
MachineInstrBuilder SelectorPHI = BuildMI(
|
|
||||||
*MBB, MBB->begin(), SDB->getCurDebugLoc(),
|
|
||||||
TII->get(TargetOpcode::PHI), FuncInfo->ExceptionSelectorVirtReg);
|
|
||||||
for (unsigned I = 0, E = LPadInst->getNumClauses(); I != E; ++I) {
|
|
||||||
// Skip filter clauses, we can't implement them.
|
|
||||||
if (LPadInst->isFilter(I))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
MachineBasicBlock *ClauseBB = MF->CreateMachineBasicBlock(LLVMBB);
|
|
||||||
MF->insert(MBB, ClauseBB);
|
|
||||||
|
|
||||||
// Add the edge from the invoke to the clause.
|
|
||||||
for (MachineBasicBlock *InvokeBB : InvokeBBs)
|
|
||||||
InvokeBB->addSuccessor(ClauseBB);
|
|
||||||
|
|
||||||
// Mark the clause as a landing pad or MI passes will delete it.
|
|
||||||
ClauseBB->setIsLandingPad();
|
|
||||||
|
|
||||||
GlobalValue *ClauseGV = ExtractTypeInfo(LPadInst->getClause(I));
|
|
||||||
|
|
||||||
// Start the BB with a label.
|
|
||||||
MCSymbol *ClauseLabel = MF->getMMI().addClauseForLandingPad(MBB);
|
|
||||||
BuildMI(*ClauseBB, ClauseBB->begin(), SDB->getCurDebugLoc(), II)
|
|
||||||
.addSym(ClauseLabel);
|
|
||||||
|
|
||||||
// Construct a simple BB that defines a register with the typeid
|
|
||||||
// constant.
|
|
||||||
FuncInfo->MBB = ClauseBB;
|
|
||||||
FuncInfo->InsertPt = ClauseBB->end();
|
|
||||||
unsigned VReg = SDB->visitLandingPadClauseBB(ClauseGV, MBB);
|
|
||||||
CurDAG->setRoot(SDB->getRoot());
|
|
||||||
SDB->clear();
|
|
||||||
CodeGenAndEmitDAG();
|
|
||||||
|
|
||||||
// Add the typeid virtual register to the phi in the main landing pad.
|
|
||||||
SelectorPHI.addReg(VReg).addMBB(ClauseBB);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the edge from the invoke to the lpad.
|
// Remove the edge from the invoke to the lpad.
|
||||||
for (MachineBasicBlock *InvokeBB : InvokeBBs)
|
for (MachineBasicBlock *InvokeBB : InvokeBBs)
|
||||||
InvokeBB->removeSuccessor(MBB);
|
InvokeBB->removeSuccessor(MBB);
|
||||||
|
|
||||||
// Restore FuncInfo back to its previous state and select the main landing
|
|
||||||
// pad block.
|
|
||||||
FuncInfo->MBB = MBB;
|
|
||||||
FuncInfo->InsertPt = MBB->end();
|
|
||||||
|
|
||||||
// Transfer EH state number assigned to the IR block to the MBB.
|
// Transfer EH state number assigned to the IR block to the MBB.
|
||||||
if (Personality == EHPersonality::MSVC_CXX) {
|
if (Personality == EHPersonality::MSVC_CXX) {
|
||||||
WinEHFuncInfo &FI = MF->getMMI().getWinEHFuncInfo(MF->getFunction());
|
WinEHFuncInfo &FI = MF->getMMI().getWinEHFuncInfo(MF->getFunction());
|
||||||
MF->getMMI().addWinEHState(MBB, FI.LandingPadStateMap[LPadInst]);
|
MF->getMMI().addWinEHState(MBB, FI.LandingPadStateMap[LPadInst]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select instructions for the landingpad if there was no llvm.eh.actions
|
// Don't select instructions for the landingpad.
|
||||||
// call.
|
return false;
|
||||||
return ActionsCall == nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark exception register as live in.
|
// Mark exception register as live in.
|
||||||
|
|
|
@ -323,11 +323,6 @@ FunctionPass *llvm::createWinEHPass(const TargetMachine *TM) {
|
||||||
return new WinEHPrepare(TM);
|
return new WinEHPrepare(TM);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Remove this once the backend can handle the prepared IR.
|
|
||||||
static cl::opt<bool>
|
|
||||||
SEHPrepare("sehprepare", cl::Hidden,
|
|
||||||
cl::desc("Prepare functions with SEH personalities"));
|
|
||||||
|
|
||||||
bool WinEHPrepare::runOnFunction(Function &Fn) {
|
bool WinEHPrepare::runOnFunction(Function &Fn) {
|
||||||
// No need to prepare outlined handlers.
|
// No need to prepare outlined handlers.
|
||||||
if (Fn.hasFnAttribute("wineh-parent"))
|
if (Fn.hasFnAttribute("wineh-parent"))
|
||||||
|
@ -355,16 +350,6 @@ bool WinEHPrepare::runOnFunction(Function &Fn) {
|
||||||
|
|
||||||
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||||
|
|
||||||
if (isAsynchronousEHPersonality(Personality) && !SEHPrepare) {
|
|
||||||
// Replace all resume instructions with unreachable.
|
|
||||||
// FIXME: Remove this once the backend can handle the prepared IR.
|
|
||||||
for (ResumeInst *Resume : Resumes) {
|
|
||||||
IRBuilder<>(Resume).CreateUnreachable();
|
|
||||||
Resume->eraseFromParent();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there were any landing pads, prepareExceptionHandlers will make changes.
|
// If there were any landing pads, prepareExceptionHandlers will make changes.
|
||||||
prepareExceptionHandlers(Fn, LPads);
|
prepareExceptionHandlers(Fn, LPads);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: opt -S -winehprepare -sehprepare < %s | FileCheck %s
|
; RUN: opt -S -winehprepare < %s | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-pc-windows-msvc"
|
target triple = "x86_64-pc-windows-msvc"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: opt -S -winehprepare -sehprepare < %s | FileCheck %s
|
; RUN: opt -S -winehprepare < %s | FileCheck %s
|
||||||
|
|
||||||
; Check that things work when the mid-level optimizer inlines the finally
|
; Check that things work when the mid-level optimizer inlines the finally
|
||||||
; block.
|
; block.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: opt -S -winehprepare -sehprepare -mtriple=x86_64-windows-msvc < %s | FileCheck %s
|
; RUN: opt -S -winehprepare -mtriple=x86_64-windows-msvc < %s | FileCheck %s
|
||||||
|
|
||||||
; Test case based on this code:
|
; Test case based on this code:
|
||||||
;
|
;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: llc -sehprepare < %s | FileCheck %s
|
; RUN: llc < %s | FileCheck %s
|
||||||
|
|
||||||
; Test case based on this code:
|
; Test case based on this code:
|
||||||
; extern "C" unsigned long _exception_code();
|
; extern "C" unsigned long _exception_code();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: opt -S -winehprepare -sehprepare < %s | FileCheck %s
|
; RUN: opt -S -winehprepare < %s | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-pc-windows-msvc"
|
target triple = "x86_64-pc-windows-msvc"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: opt -S -winehprepare -sehprepare -mtriple=x86_64-windows-msvc < %s | FileCheck %s
|
; RUN: opt -S -winehprepare -mtriple=x86_64-windows-msvc < %s | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-pc-windows-msvc"
|
target triple = "x86_64-pc-windows-msvc"
|
||||||
|
|
|
@ -1,175 +0,0 @@
|
||||||
; RUN: llc -mtriple x86_64-pc-windows-msvc < %s | FileCheck %s
|
|
||||||
|
|
||||||
define void @two_invoke_merged() {
|
|
||||||
entry:
|
|
||||||
invoke void @try_body()
|
|
||||||
to label %again unwind label %lpad
|
|
||||||
|
|
||||||
again:
|
|
||||||
invoke void @try_body()
|
|
||||||
to label %done unwind label %lpad
|
|
||||||
|
|
||||||
done:
|
|
||||||
ret void
|
|
||||||
|
|
||||||
lpad:
|
|
||||||
%vals = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
|
|
||||||
catch i8* bitcast (i32 (i8*, i8*)* @filt0 to i8*)
|
|
||||||
catch i8* bitcast (i32 (i8*, i8*)* @filt1 to i8*)
|
|
||||||
%sel = extractvalue { i8*, i32 } %vals, 1
|
|
||||||
call void @use_selector(i32 %sel)
|
|
||||||
ret void
|
|
||||||
}
|
|
||||||
|
|
||||||
; Normal path code
|
|
||||||
|
|
||||||
; CHECK-LABEL: {{^}}two_invoke_merged:
|
|
||||||
; CHECK: .seh_proc two_invoke_merged
|
|
||||||
; CHECK: .seh_handler __C_specific_handler, @unwind, @except
|
|
||||||
; CHECK: .Ltmp0:
|
|
||||||
; CHECK: callq try_body
|
|
||||||
; CHECK-NEXT: .Ltmp1:
|
|
||||||
; CHECK: .Ltmp2:
|
|
||||||
; CHECK: callq try_body
|
|
||||||
; CHECK-NEXT: .Ltmp3:
|
|
||||||
; CHECK: retq
|
|
||||||
|
|
||||||
; Landing pad code
|
|
||||||
|
|
||||||
; CHECK: .Ltmp5:
|
|
||||||
; CHECK: movl $1, %ecx
|
|
||||||
; CHECK: jmp
|
|
||||||
; CHECK: .Ltmp6:
|
|
||||||
; CHECK: movl $2, %ecx
|
|
||||||
; CHECK: callq use_selector
|
|
||||||
|
|
||||||
; CHECK: .seh_handlerdata
|
|
||||||
; CHECK-NEXT: .long 2
|
|
||||||
; CHECK-NEXT: .long .Ltmp0@IMGREL
|
|
||||||
; CHECK-NEXT: .long .Ltmp3@IMGREL+1
|
|
||||||
; CHECK-NEXT: .long filt0@IMGREL
|
|
||||||
; CHECK-NEXT: .long .Ltmp5@IMGREL
|
|
||||||
; CHECK-NEXT: .long .Ltmp0@IMGREL
|
|
||||||
; CHECK-NEXT: .long .Ltmp3@IMGREL+1
|
|
||||||
; CHECK-NEXT: .long filt1@IMGREL
|
|
||||||
; CHECK-NEXT: .long .Ltmp6@IMGREL
|
|
||||||
; CHECK: .text
|
|
||||||
; CHECK: .seh_endproc
|
|
||||||
|
|
||||||
define void @two_invoke_gap() {
|
|
||||||
entry:
|
|
||||||
invoke void @try_body()
|
|
||||||
to label %again unwind label %lpad
|
|
||||||
|
|
||||||
again:
|
|
||||||
call void @do_nothing_on_unwind()
|
|
||||||
invoke void @try_body()
|
|
||||||
to label %done unwind label %lpad
|
|
||||||
|
|
||||||
done:
|
|
||||||
ret void
|
|
||||||
|
|
||||||
lpad:
|
|
||||||
%vals = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
|
|
||||||
catch i8* bitcast (i32 (i8*, i8*)* @filt0 to i8*)
|
|
||||||
%sel = extractvalue { i8*, i32 } %vals, 1
|
|
||||||
call void @use_selector(i32 %sel)
|
|
||||||
ret void
|
|
||||||
}
|
|
||||||
|
|
||||||
; Normal path code
|
|
||||||
|
|
||||||
; CHECK-LABEL: {{^}}two_invoke_gap:
|
|
||||||
; CHECK: .seh_proc two_invoke_gap
|
|
||||||
; CHECK: .seh_handler __C_specific_handler, @unwind, @except
|
|
||||||
; CHECK: .Ltmp11:
|
|
||||||
; CHECK: callq try_body
|
|
||||||
; CHECK-NEXT: .Ltmp12:
|
|
||||||
; CHECK: callq do_nothing_on_unwind
|
|
||||||
; CHECK: .Ltmp13:
|
|
||||||
; CHECK: callq try_body
|
|
||||||
; CHECK-NEXT: .Ltmp14:
|
|
||||||
; CHECK: retq
|
|
||||||
|
|
||||||
; Landing pad code
|
|
||||||
|
|
||||||
; CHECK: .Ltmp16:
|
|
||||||
; CHECK: movl $1, %ecx
|
|
||||||
; CHECK: callq use_selector
|
|
||||||
|
|
||||||
; CHECK: .seh_handlerdata
|
|
||||||
; CHECK-NEXT: .long 2
|
|
||||||
; CHECK-NEXT: .long .Ltmp11@IMGREL
|
|
||||||
; CHECK-NEXT: .long .Ltmp12@IMGREL+1
|
|
||||||
; CHECK-NEXT: .long filt0@IMGREL
|
|
||||||
; CHECK-NEXT: .long .Ltmp16@IMGREL
|
|
||||||
; CHECK-NEXT: .long .Ltmp13@IMGREL
|
|
||||||
; CHECK-NEXT: .long .Ltmp14@IMGREL+1
|
|
||||||
; CHECK-NEXT: .long filt0@IMGREL
|
|
||||||
; CHECK-NEXT: .long .Ltmp16@IMGREL
|
|
||||||
; CHECK: .text
|
|
||||||
; CHECK: .seh_endproc
|
|
||||||
|
|
||||||
define void @two_invoke_nounwind_gap() {
|
|
||||||
entry:
|
|
||||||
invoke void @try_body()
|
|
||||||
to label %again unwind label %lpad
|
|
||||||
|
|
||||||
again:
|
|
||||||
call void @cannot_unwind()
|
|
||||||
invoke void @try_body()
|
|
||||||
to label %done unwind label %lpad
|
|
||||||
|
|
||||||
done:
|
|
||||||
ret void
|
|
||||||
|
|
||||||
lpad:
|
|
||||||
%vals = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)
|
|
||||||
catch i8* bitcast (i32 (i8*, i8*)* @filt0 to i8*)
|
|
||||||
%sel = extractvalue { i8*, i32 } %vals, 1
|
|
||||||
call void @use_selector(i32 %sel)
|
|
||||||
ret void
|
|
||||||
}
|
|
||||||
|
|
||||||
; Normal path code
|
|
||||||
|
|
||||||
; CHECK-LABEL: {{^}}two_invoke_nounwind_gap:
|
|
||||||
; CHECK: .seh_proc two_invoke_nounwind_gap
|
|
||||||
; CHECK: .seh_handler __C_specific_handler, @unwind, @except
|
|
||||||
; CHECK: .Ltmp21:
|
|
||||||
; CHECK: callq try_body
|
|
||||||
; CHECK-NEXT: .Ltmp22:
|
|
||||||
; CHECK: callq cannot_unwind
|
|
||||||
; CHECK: .Ltmp23:
|
|
||||||
; CHECK: callq try_body
|
|
||||||
; CHECK-NEXT: .Ltmp24:
|
|
||||||
; CHECK: retq
|
|
||||||
|
|
||||||
; Landing pad code
|
|
||||||
|
|
||||||
; CHECK: .Ltmp26:
|
|
||||||
; CHECK: movl $1, %ecx
|
|
||||||
; CHECK: callq use_selector
|
|
||||||
|
|
||||||
; CHECK: .seh_handlerdata
|
|
||||||
; CHECK-NEXT: .long 1
|
|
||||||
; CHECK-NEXT: .long .Ltmp21@IMGREL
|
|
||||||
; CHECK-NEXT: .long .Ltmp24@IMGREL+1
|
|
||||||
; CHECK-NEXT: .long filt0@IMGREL
|
|
||||||
; CHECK-NEXT: .long .Ltmp26@IMGREL
|
|
||||||
; CHECK: .text
|
|
||||||
; CHECK: .seh_endproc
|
|
||||||
|
|
||||||
declare void @try_body()
|
|
||||||
declare void @do_nothing_on_unwind()
|
|
||||||
declare void @cannot_unwind() nounwind
|
|
||||||
declare void @use_selector(i32)
|
|
||||||
|
|
||||||
declare i32 @filt0(i8* %eh_info, i8* %rsp)
|
|
||||||
declare i32 @filt1(i8* %eh_info, i8* %rsp)
|
|
||||||
|
|
||||||
declare void @handler0()
|
|
||||||
declare void @handler1()
|
|
||||||
|
|
||||||
declare i32 @__C_specific_handler(...)
|
|
||||||
declare i32 @llvm.eh.typeid.for(i8*) readnone nounwind
|
|
|
@ -1,4 +1,3 @@
|
||||||
; RUN: llc -sehprepare -mtriple=x86_64-windows-msvc < %s | FileCheck %s
|
|
||||||
; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s
|
; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s
|
||||||
|
|
||||||
@str = internal unnamed_addr constant [10 x i8] c"recovered\00", align 1
|
@str = internal unnamed_addr constant [10 x i8] c"recovered\00", align 1
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: llc -sehprepare < %s | FileCheck %s
|
; RUN: llc < %s | FileCheck %s
|
||||||
|
|
||||||
; Test case based on this source:
|
; Test case based on this source:
|
||||||
; int puts(const char*);
|
; int puts(const char*);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: llc -sehprepare -mtriple=x86_64-windows-msvc < %s | FileCheck %s
|
; RUN: llc -mtriple=x86_64-windows-msvc < %s | FileCheck %s
|
||||||
|
|
||||||
@str_recovered = internal unnamed_addr constant [10 x i8] c"recovered\00", align 1
|
@str_recovered = internal unnamed_addr constant [10 x i8] c"recovered\00", align 1
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: llc -sehprepare -mtriple x86_64-pc-windows-msvc < %s | FileCheck %s
|
; RUN: llc -mtriple x86_64-pc-windows-msvc < %s | FileCheck %s
|
||||||
|
|
||||||
; This test case is also intended to be run manually as a complete functional
|
; This test case is also intended to be run manually as a complete functional
|
||||||
; test. It should link, print something, and exit zero rather than crashing.
|
; test. It should link, print something, and exit zero rather than crashing.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; RUN: opt -S -winehprepare -sehprepare -dwarfehprepare -mtriple x86_64-pc-windows-msvc < %s | FileCheck %s
|
; RUN: opt -S -winehprepare -dwarfehprepare -mtriple x86_64-pc-windows-msvc < %s | FileCheck %s
|
||||||
|
|
||||||
; FIXME: Add and test outlining here.
|
; FIXME: Add and test outlining here.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue