[WinEH] Remove unreachable blocks before preparation
authorDavid Majnemer <david.majnemer@gmail.com>
Wed, 7 Oct 2015 21:08:25 +0000 (21:08 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Wed, 7 Oct 2015 21:08:25 +0000 (21:08 +0000)
We remove unreachable blocks because it is pointless to consider them
for coloring.  However, we still had stale pointers to these blocks in
some data structures after we removed them from the function.

Instead, remove the unreachable blocks before attempting to do anything
with the function.

This fixes PR25099.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249617 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/WinEHPrepare.cpp
test/CodeGen/WinEH/cppeh-catch-all.ll [deleted file]
test/CodeGen/WinEH/wineh-cloning.ll
test/CodeGen/X86/cppeh-nounwind.ll [deleted file]

index ddbe000..5141df6 100644 (file)
@@ -437,6 +437,11 @@ bool WinEHPrepare::runOnFunction(Function &Fn) {
   if (!isFuncletEHPersonality(Personality))
     return false;
 
+  // Remove unreachable blocks.  It is not valuable to assign them a color and
+  // their existence can trick us into thinking values are alive when they are
+  // not.
+  removeUnreachableBlocks(Fn);
+
   SmallVector<LandingPadInst *, 4> LPads;
   SmallVector<ResumeInst *, 4> Resumes;
   SmallVector<BasicBlock *, 4> EntryBlocks;
@@ -3408,11 +3413,6 @@ void WinEHPrepare::verifyPreparedFunclets(Function &F) {
 
 bool WinEHPrepare::prepareExplicitEH(
     Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks) {
-  // Remove unreachable blocks.  It is not valuable to assign them a color and
-  // their existence can trick us into thinking values are alive when they are
-  // not.
-  removeUnreachableBlocks(F);
-
   replaceTerminatePadWithCleanup(F);
 
   // Determine which blocks are reachable from which funclet entries.
diff --git a/test/CodeGen/WinEH/cppeh-catch-all.ll b/test/CodeGen/WinEH/cppeh-catch-all.ll
deleted file mode 100644 (file)
index 266dd3e..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-; RUN: opt -mtriple=x86_64-pc-windows-msvc -winehprepare -S -o - < %s | FileCheck %s
-
-; This test is based on the following code:
-;
-; void test()
-; {
-;   try {
-;     may_throw();
-;   } catch (...) {
-;     handle_exception();
-;   }
-; }
-;
-; Parts of the IR have been hand-edited to simplify the test case.
-; The full IR will be restored when Windows C++ EH support is complete.
-
-; ModuleID = 'catch-all.cpp'
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-pc-windows-msvc"
-
-; The function entry in this case remains unchanged.
-; CHECK: define void @_Z4testv()
-; CHECK: entry:
-; CHECK:   invoke void @_Z9may_throwv()
-; CHECK:           to label %invoke.cont unwind label %[[LPAD_LABEL:lpad[0-9]*]]
-
-; Function Attrs: uwtable
-define void @_Z4testv() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
-entry:
-  %exn.slot = alloca i8*
-  %ehselector.slot = alloca i32
-  invoke void @_Z9may_throwv()
-          to label %invoke.cont unwind label %lpad
-
-invoke.cont:                                      ; preds = %entry
-  br label %try.cont
-
-; CHECK: [[LPAD_LABEL]]:{{[ ]+}}; preds = %entry
-; CHECK:   landingpad { i8*, i32 }
-; CHECK-NEXT:           catch i8* null
-; CHECK-NEXT:   [[RECOVER:\%.+]] = call i8* (...) @llvm.eh.actions(i32 1, i8* null, i32 -1, i8* (i8*, i8*)* @_Z4testv.catch)
-; CHECK-NEXT:   indirectbr i8* [[RECOVER]], [label %try.cont]
-
-lpad:                                             ; preds = %entry
-  %tmp = landingpad { i8*, i32 }
-          catch i8* null
-  %tmp1 = extractvalue { i8*, i32 } %tmp, 0
-  store i8* %tmp1, i8** %exn.slot
-  %tmp2 = extractvalue { i8*, i32 } %tmp, 1
-  store i32 %tmp2, i32* %ehselector.slot
-  br label %catch
-
-; CHECK-NOT: catch:
-
-catch:                                            ; preds = %lpad
-  %exn = load i8*, i8** %exn.slot
-  call void @llvm.eh.begincatch(i8* %exn, i8* null) #2
-  call void @_Z16handle_exceptionv()
-  br label %invoke.cont2
-
-; CHECK-NOT: invoke.cont2:
-
-invoke.cont2:                                     ; preds = %catch
-  call void @llvm.eh.endcatch()
-  br label %try.cont
-
-try.cont:                                         ; preds = %invoke.cont2, %invoke.cont
-  ret void
-
-; CHECK: }
-}
-
-; CHECK: define internal i8* @_Z4testv.catch(i8*, i8*)
-; CHECK: entry:
-; CHECK:   call void @_Z16handle_exceptionv()
-; CHECK:   ret i8* blockaddress(@_Z4testv, %try.cont)
-; CHECK: }
-
-declare void @_Z9may_throwv() #1
-
-declare i32 @__CxxFrameHandler3(...)
-
-declare void @llvm.eh.begincatch(i8*, i8*)
-
-declare void @_Z16handle_exceptionv() #1
-
-declare void @llvm.eh.endcatch()
-
-attributes #0 = { uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
-attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
-attributes #2 = { noinline noreturn nounwind }
-attributes #3 = { nounwind }
-attributes #4 = { noreturn nounwind }
-
-!llvm.ident = !{!0}
-
-!0 = !{!"clang version 3.7.0 (trunk 226027)"}
index 72bbeaf..ed5e149 100644 (file)
@@ -475,6 +475,17 @@ exit:
   ret void
 }
 
+; CHECK-LABEL: define void @test13()
+; CHECK: ret void
+define void @test13() personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+  ret void
+
+unreachable:
+  cleanuppad []
+  unreachable
+}
+
 ; Make sure the DISubprogram doesn't get cloned
 ; CHECK-LABEL: !llvm.module.flags
 ; CHECK-NOT: !DISubprogram
diff --git a/test/CodeGen/X86/cppeh-nounwind.ll b/test/CodeGen/X86/cppeh-nounwind.ll
deleted file mode 100644 (file)
index d9bc001..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-; RUN: llc -mtriple=i686-pc-windows-msvc < %s | FileCheck %s
-
-; Sometimes invokes of nounwind functions make it through to CodeGen, especially
-; at -O0, where Clang sometimes optimistically annotates functions as nounwind.
-; WinEHPrepare ends up outlining functions, and emitting references to LSDA
-; labels. Make sure we emit the LSDA in that case.
-
-declare i32 @__CxxFrameHandler3(...)
-declare void @nounwind_func() nounwind
-declare void @cleanup()
-
-define void @should_emit_tables() personality i32 (...)* @__CxxFrameHandler3 {
-entry:
-  invoke void @nounwind_func()
-      to label %done unwind label %lpad
-
-done:
-  ret void
-
-lpad:
-  %vals = landingpad { i8*, i32 }
-      cleanup
-  call void @cleanup()
-  resume { i8*, i32 } %vals
-}
-
-; CHECK: _should_emit_tables:
-; CHECK: calll _nounwind_func
-; CHECK: retl
-
-; CHECK: L__ehtable$should_emit_tables:
-
-; CHECK: ___ehhandler$should_emit_tables:
-; CHECK: movl $L__ehtable$should_emit_tables, %eax
-; CHECK: jmp ___CxxFrameHandler3 # TAILCALL