From 5c5facc2ce1b8469494e37c07f69223e3bc45d2c Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 23 Apr 2015 23:22:33 +0000 Subject: [PATCH] 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 --- llvm/include/llvm/CodeGen/MachineModuleInfo.h | 6 - llvm/lib/CodeGen/AsmPrinter/Win64Exception.cpp | 40 ----- llvm/lib/CodeGen/MachineModuleInfo.cpp | 8 - llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 60 +------ llvm/lib/CodeGen/WinEHPrepare.cpp | 15 -- llvm/test/CodeGen/WinEH/seh-catch-all.ll | 2 +- llvm/test/CodeGen/WinEH/seh-inlined-finally.ll | 2 +- llvm/test/CodeGen/WinEH/seh-outlined-finally.ll | 2 +- llvm/test/CodeGen/WinEH/seh-prepared-basic.ll | 2 +- llvm/test/CodeGen/WinEH/seh-resume-phi.ll | 2 +- llvm/test/CodeGen/WinEH/seh-simple.ll | 2 +- llvm/test/CodeGen/X86/seh-basic.ll | 175 --------------------- llvm/test/CodeGen/X86/seh-catch-all.ll | 1 - llvm/test/CodeGen/X86/seh-except-finally.ll | 2 +- llvm/test/CodeGen/X86/seh-finally.ll | 2 +- llvm/test/CodeGen/X86/seh-safe-div.ll | 2 +- llvm/test/CodeGen/X86/win_eh_prepare.ll | 2 +- 17 files changed, 12 insertions(+), 313 deletions(-) delete mode 100644 llvm/test/CodeGen/X86/seh-basic.ll diff --git a/llvm/include/llvm/CodeGen/MachineModuleInfo.h b/llvm/include/llvm/CodeGen/MachineModuleInfo.h index d631f7c..d53fdd4 100644 --- a/llvm/include/llvm/CodeGen/MachineModuleInfo.h +++ b/llvm/include/llvm/CodeGen/MachineModuleInfo.h @@ -77,7 +77,6 @@ struct LandingPadInfo { MachineBasicBlock *LandingPadBlock; // Landing pad block. SmallVector BeginLabels; // Labels prior to invoke. SmallVector EndLabels; // Labels after invoke. - SmallVector ClauseLabels; // Labels for each clause. SmallVector SEHHandlers; // SEH handlers active at this lpad. MCSymbol *LandingPadLabel; // Label at beginning of landing pad. const Function *Personality; // Personality function. @@ -361,11 +360,6 @@ public: /// 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, const BlockAddress *RecoverLabel); diff --git a/llvm/lib/CodeGen/AsmPrinter/Win64Exception.cpp b/llvm/lib/CodeGen/AsmPrinter/Win64Exception.cpp index 2737a53..be15989 100644 --- a/llvm/lib/CodeGen/AsmPrinter/Win64Exception.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/Win64Exception.cpp @@ -206,12 +206,6 @@ void Win64Exception::emitCSpecificHandlerTable() { for (const CallSiteEntry &CSE : CallSites) { if (!CSE.LPad) 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(); } Asm->OutStreamer.EmitIntValue(NumEntries, 4); @@ -267,40 +261,6 @@ void Win64Exception::emitCSpecificHandlerTable() { else 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 &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); - } } } diff --git a/llvm/lib/CodeGen/MachineModuleInfo.cpp b/llvm/lib/CodeGen/MachineModuleInfo.cpp index e4f2aea..2352692 100644 --- a/llvm/lib/CodeGen/MachineModuleInfo.cpp +++ b/llvm/lib/CodeGen/MachineModuleInfo.cpp @@ -461,14 +461,6 @@ void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) { 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, const Function *Filter, const BlockAddress *RecoverBA) { diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 982d719..f3735cb 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -955,76 +955,20 @@ bool SelectionDAGISel::PrepareEHLandingPad() { // Mark the clause as a landing pad or MI passes will delete it. 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. for (MachineBasicBlock *InvokeBB : InvokeBBs) 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. if (Personality == EHPersonality::MSVC_CXX) { WinEHFuncInfo &FI = MF->getMMI().getWinEHFuncInfo(MF->getFunction()); MF->getMMI().addWinEHState(MBB, FI.LandingPadStateMap[LPadInst]); } - // Select instructions for the landingpad if there was no llvm.eh.actions - // call. - return ActionsCall == nullptr; + // Don't select instructions for the landingpad. + return false; } // Mark exception register as live in. diff --git a/llvm/lib/CodeGen/WinEHPrepare.cpp b/llvm/lib/CodeGen/WinEHPrepare.cpp index b1eea7d..09f3e13 100644 --- a/llvm/lib/CodeGen/WinEHPrepare.cpp +++ b/llvm/lib/CodeGen/WinEHPrepare.cpp @@ -323,11 +323,6 @@ FunctionPass *llvm::createWinEHPass(const TargetMachine *TM) { return new WinEHPrepare(TM); } -// FIXME: Remove this once the backend can handle the prepared IR. -static cl::opt - SEHPrepare("sehprepare", cl::Hidden, - cl::desc("Prepare functions with SEH personalities")); - bool WinEHPrepare::runOnFunction(Function &Fn) { // No need to prepare outlined handlers. if (Fn.hasFnAttribute("wineh-parent")) @@ -355,16 +350,6 @@ bool WinEHPrepare::runOnFunction(Function &Fn) { DT = &getAnalysis().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. prepareExceptionHandlers(Fn, LPads); return true; diff --git a/llvm/test/CodeGen/WinEH/seh-catch-all.ll b/llvm/test/CodeGen/WinEH/seh-catch-all.ll index fb2b9ba..ab6c9ef 100644 --- a/llvm/test/CodeGen/WinEH/seh-catch-all.ll +++ b/llvm/test/CodeGen/WinEH/seh-catch-all.ll @@ -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 triple = "x86_64-pc-windows-msvc" diff --git a/llvm/test/CodeGen/WinEH/seh-inlined-finally.ll b/llvm/test/CodeGen/WinEH/seh-inlined-finally.ll index 54045f8..d2080cf 100644 --- a/llvm/test/CodeGen/WinEH/seh-inlined-finally.ll +++ b/llvm/test/CodeGen/WinEH/seh-inlined-finally.ll @@ -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 ; block. diff --git a/llvm/test/CodeGen/WinEH/seh-outlined-finally.ll b/llvm/test/CodeGen/WinEH/seh-outlined-finally.ll index bc9d322..19558b7 100644 --- a/llvm/test/CodeGen/WinEH/seh-outlined-finally.ll +++ b/llvm/test/CodeGen/WinEH/seh-outlined-finally.ll @@ -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: ; diff --git a/llvm/test/CodeGen/WinEH/seh-prepared-basic.ll b/llvm/test/CodeGen/WinEH/seh-prepared-basic.ll index 0c6850a..880bb3c 100644 --- a/llvm/test/CodeGen/WinEH/seh-prepared-basic.ll +++ b/llvm/test/CodeGen/WinEH/seh-prepared-basic.ll @@ -1,4 +1,4 @@ -; RUN: llc -sehprepare < %s | FileCheck %s +; RUN: llc < %s | FileCheck %s ; Test case based on this code: ; extern "C" unsigned long _exception_code(); diff --git a/llvm/test/CodeGen/WinEH/seh-resume-phi.ll b/llvm/test/CodeGen/WinEH/seh-resume-phi.ll index 398cbc4..cd30bfc 100644 --- a/llvm/test/CodeGen/WinEH/seh-resume-phi.ll +++ b/llvm/test/CodeGen/WinEH/seh-resume-phi.ll @@ -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 triple = "x86_64-pc-windows-msvc" diff --git a/llvm/test/CodeGen/WinEH/seh-simple.ll b/llvm/test/CodeGen/WinEH/seh-simple.ll index 6d9ee1c..a2a2139 100644 --- a/llvm/test/CodeGen/WinEH/seh-simple.ll +++ b/llvm/test/CodeGen/WinEH/seh-simple.ll @@ -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 triple = "x86_64-pc-windows-msvc" diff --git a/llvm/test/CodeGen/X86/seh-basic.ll b/llvm/test/CodeGen/X86/seh-basic.ll deleted file mode 100644 index 69d70d7..0000000 --- a/llvm/test/CodeGen/X86/seh-basic.ll +++ /dev/null @@ -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 diff --git a/llvm/test/CodeGen/X86/seh-catch-all.ll b/llvm/test/CodeGen/X86/seh-catch-all.ll index a224da5..931046e 100644 --- a/llvm/test/CodeGen/X86/seh-catch-all.ll +++ b/llvm/test/CodeGen/X86/seh-catch-all.ll @@ -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 @str = internal unnamed_addr constant [10 x i8] c"recovered\00", align 1 diff --git a/llvm/test/CodeGen/X86/seh-except-finally.ll b/llvm/test/CodeGen/X86/seh-except-finally.ll index 42f7d72..c796f1e 100644 --- a/llvm/test/CodeGen/X86/seh-except-finally.ll +++ b/llvm/test/CodeGen/X86/seh-except-finally.ll @@ -1,4 +1,4 @@ -; RUN: llc -sehprepare < %s | FileCheck %s +; RUN: llc < %s | FileCheck %s ; Test case based on this source: ; int puts(const char*); diff --git a/llvm/test/CodeGen/X86/seh-finally.ll b/llvm/test/CodeGen/X86/seh-finally.ll index e6d1f1b..91baed5 100644 --- a/llvm/test/CodeGen/X86/seh-finally.ll +++ b/llvm/test/CodeGen/X86/seh-finally.ll @@ -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 diff --git a/llvm/test/CodeGen/X86/seh-safe-div.ll b/llvm/test/CodeGen/X86/seh-safe-div.ll index 1f9e22c..80b15b6 100644 --- a/llvm/test/CodeGen/X86/seh-safe-div.ll +++ b/llvm/test/CodeGen/X86/seh-safe-div.ll @@ -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 ; test. It should link, print something, and exit zero rather than crashing. diff --git a/llvm/test/CodeGen/X86/win_eh_prepare.ll b/llvm/test/CodeGen/X86/win_eh_prepare.ll index 3e513e0..a33dd92 100644 --- a/llvm/test/CodeGen/X86/win_eh_prepare.ll +++ b/llvm/test/CodeGen/X86/win_eh_prepare.ll @@ -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. -- 2.7.4