Add an IR-to-IR test for dwarf EH preparation using opt
authorReid Kleckner <reid@kleckner.net>
Wed, 18 Feb 2015 23:17:41 +0000 (23:17 +0000)
committerReid Kleckner <reid@kleckner.net>
Wed, 18 Feb 2015 23:17:41 +0000 (23:17 +0000)
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
lib/CodeGen/DwarfEHPrepare.cpp
test/CodeGen/X86/dwarf-eh-prepare.ll [new file with mode: 0644]
tools/opt/opt.cpp

index b42d12060a4fea9d2ba919d763af40917f183f40..d488a9fed7764652f79d57c2dfe3444ea56a9745 100644 (file)
@@ -292,6 +292,7 @@ void initializeRewriteSymbolsPass(PassRegistry&);
 void initializeWinEHPreparePass(PassRegistry&);
 void initializePlaceBackedgeSafepointsImplPass(PassRegistry&);
 void initializePlaceSafepointsPass(PassRegistry&);
+void initializeDwarfEHPreparePass(PassRegistry&);
 }
 
 #endif
index 8e49ef31bd46fd49dd39c68cfa8660c70c1e9bef..7b47a48391c7bbcbcc029b4c0a37ed9c9abb913e 100644 (file)
@@ -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 (file)
index 0000000..a3a70da
--- /dev/null
@@ -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*)
index 59b63093b36d45711c25ad78b2dd4d179dffa70c..d9525259ed228352f257aac5732b6fd91910586f 100644 (file)
@@ -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);