From f89d9b1c75d0a1db28425670076a369172bc98bb Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Wed, 18 Feb 2015 23:17:41 +0000 Subject: [PATCH] Add an IR-to-IR test for dwarf EH preparation using opt This tests the simple resume instruction elimination logic that we have before making some changes to it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229768 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/InitializePasses.h | 1 + lib/CodeGen/DwarfEHPrepare.cpp | 8 +++++ test/CodeGen/X86/dwarf-eh-prepare.ll | 51 ++++++++++++++++++++++++++++ tools/opt/opt.cpp | 1 + 4 files changed, 61 insertions(+) create mode 100644 test/CodeGen/X86/dwarf-eh-prepare.ll diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index b42d12060a4..d488a9fed77 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -292,6 +292,7 @@ void initializeRewriteSymbolsPass(PassRegistry&); void initializeWinEHPreparePass(PassRegistry&); void initializePlaceBackedgeSafepointsImplPass(PassRegistry&); void initializePlaceSafepointsPass(PassRegistry&); +void initializeDwarfEHPreparePass(PassRegistry&); } #endif diff --git a/lib/CodeGen/DwarfEHPrepare.cpp b/lib/CodeGen/DwarfEHPrepare.cpp index 8e49ef31bd4..7b47a48391c 100644 --- a/lib/CodeGen/DwarfEHPrepare.cpp +++ b/lib/CodeGen/DwarfEHPrepare.cpp @@ -38,6 +38,11 @@ namespace { public: static char ID; // Pass identification, replacement for typeid. + + // INITIALIZE_TM_PASS requires a default constructor, but it isn't used in + // practice. + DwarfEHPrepare() : FunctionPass(ID), TM(nullptr), RewindFunction(nullptr) {} + DwarfEHPrepare(const TargetMachine *TM) : FunctionPass(ID), TM(TM), RewindFunction(nullptr) {} @@ -55,6 +60,8 @@ namespace { } // end anonymous namespace char DwarfEHPrepare::ID = 0; +INITIALIZE_TM_PASS(DwarfEHPrepare, "dwarfehprepare", "Prepare DWARF exceptions", + false, false) FunctionPass *llvm::createDwarfEHPass(const TargetMachine *TM) { return new DwarfEHPrepare(TM); @@ -167,6 +174,7 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls(Function &Fn) { } bool DwarfEHPrepare::runOnFunction(Function &Fn) { + assert(TM && "DWARF EH preparation requires a target machine"); bool Changed = InsertUnwindResumeCalls(Fn); return Changed; } diff --git a/test/CodeGen/X86/dwarf-eh-prepare.ll b/test/CodeGen/X86/dwarf-eh-prepare.ll new file mode 100644 index 00000000000..a3a70da866c --- /dev/null +++ b/test/CodeGen/X86/dwarf-eh-prepare.ll @@ -0,0 +1,51 @@ +; RUN: opt -mtriple=x86_64-linux-gnu -dwarfehprepare < %s -S | FileCheck %s + +; Check basic functionality of IR-to-IR DWARF EH preparation. This should +; eliminate resumes. This pass requires a TargetMachine, so we put it under X86 +; and provide an x86 triple. + +@int_typeinfo = global i8 0 + +declare void @might_throw() + +define i32 @simple_catch() { + invoke void @might_throw() + to label %cont unwind label %lpad + +; CHECK: define i32 @simple_catch() +; CHECK: invoke void @might_throw() + +cont: + ret i32 0 + +; CHECK: ret i32 0 + +lpad: + %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0 + catch i8* @int_typeinfo + %ehptr = extractvalue { i8*, i32 } %ehvals, 0 + %ehsel = extractvalue { i8*, i32 } %ehvals, 1 + %int_sel = call i32 @llvm.eh.typeid.for(i8* @int_typeinfo) + %int_match = icmp eq i32 %ehsel, %int_sel + br i1 %int_match, label %catch_int, label %eh.resume + +; CHECK: lpad: +; CHECK: landingpad { i8*, i32 } personality i32 (...)* @__gxx_personality_v0 +; CHECK: call i32 @llvm.eh.typeid.for +; CHECK: br i1 + +catch_int: + ret i32 1 + +; CHECK: catch_int: +; CHECK: ret i32 1 + +eh.resume: + resume { i8*, i32 } %ehvals + +; CHECK: eh.resume: +; CHECK: call void @_Unwind_Resume(i8* %{{.*}}) +} + +declare i32 @__gxx_personality_v0(...) +declare i32 @llvm.eh.typeid.for(i8*) diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 59b63093b36..d9525259ed2 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -325,6 +325,7 @@ int main(int argc, char **argv) { initializeAtomicExpandPass(Registry); initializeRewriteSymbolsPass(Registry); initializeWinEHPreparePass(Registry); + initializeDwarfEHPreparePass(Registry); #ifdef LINK_POLLY_INTO_TOOLS polly::initializePollyPasses(Registry); -- 2.34.1