From fae66468fddb275831b4bfa77316489906271ecc Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Wed, 7 Oct 2015 21:08:25 +0000 Subject: [PATCH] [WinEH] Remove unreachable blocks before preparation 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 | 10 +-- test/CodeGen/WinEH/cppeh-catch-all.ll | 97 --------------------------- test/CodeGen/WinEH/wineh-cloning.ll | 11 +++ test/CodeGen/X86/cppeh-nounwind.ll | 35 ---------- 4 files changed, 16 insertions(+), 137 deletions(-) delete mode 100644 test/CodeGen/WinEH/cppeh-catch-all.ll delete mode 100644 test/CodeGen/X86/cppeh-nounwind.ll diff --git a/lib/CodeGen/WinEHPrepare.cpp b/lib/CodeGen/WinEHPrepare.cpp index ddbe0002411..5141df6cc85 100644 --- a/lib/CodeGen/WinEHPrepare.cpp +++ b/lib/CodeGen/WinEHPrepare.cpp @@ -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 LPads; SmallVector Resumes; SmallVector EntryBlocks; @@ -3408,11 +3413,6 @@ void WinEHPrepare::verifyPreparedFunclets(Function &F) { bool WinEHPrepare::prepareExplicitEH( Function &F, SmallVectorImpl &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 index 266dd3e305c..00000000000 --- a/test/CodeGen/WinEH/cppeh-catch-all.ll +++ /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)"} diff --git a/test/CodeGen/WinEH/wineh-cloning.ll b/test/CodeGen/WinEH/wineh-cloning.ll index 72bbeaf55f7..ed5e149d658 100644 --- a/test/CodeGen/WinEH/wineh-cloning.ll +++ b/test/CodeGen/WinEH/wineh-cloning.ll @@ -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 index d9bc001a92d..00000000000 --- a/test/CodeGen/X86/cppeh-nounwind.ll +++ /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 -- 2.34.1