[EH] Create removeUnwindEdge utility

Summary:
Factor the code that rewrites invokes to calls and rewrites WinEH
terminators to their "unwind to caller" equivalents into a helper in
Utils/Local, and use it in the three places I'm aware of that need to do
this.


Reviewers: andrew.w.kaylor, majnemer, rnk

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D13152

llvm-svn: 248677
diff --git a/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll b/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll
new file mode 100644
index 0000000..7db883b
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/wineh-unreachable.ll
@@ -0,0 +1,88 @@
+; RUN: opt -S -simplifycfg < %s | FileCheck %s
+
+declare void @Personality()
+declare void @f()
+
+; CHECK-LABEL: define void @test1()
+define void @test1() personality i8* bitcast (void ()* @Personality to i8*) {
+entry:
+  ; CHECK: call void @f()
+  invoke void @f()
+    to label %exit unwind label %unreachable.unwind
+exit:
+  ret void
+unreachable.unwind:
+  cleanuppad []
+  unreachable  
+}
+
+; CHECK-LABEL: define void @test2()
+define void @test2() personality i8* bitcast (void ()* @Personality to i8*) {
+entry:
+  invoke void @f()
+    to label %exit unwind label %catch.pad
+catch.pad:
+  ; CHECK: catchpad []
+  ; CHECK-NEXT: to label %catch.body unwind label %catch.end
+  %catch = catchpad []
+    to label %catch.body unwind label %catch.end
+catch.body:
+  ; CHECK:      catch.body:
+  ; CHECK-NEXT:   call void @f()
+  ; CHECK-NEXT:   unreachable
+  call void @f()
+  catchret %catch to label %unreachable
+catch.end:
+  ; CHECK: catch.end:
+  ; CHECK-NEXT: catchendpad unwind to caller
+  catchendpad unwind label %unreachable.unwind
+exit:
+  ret void
+unreachable.unwind:
+  cleanuppad []
+  unreachable
+unreachable:
+  unreachable
+}
+
+; CHECK-LABEL: define void @test3()
+define void @test3() personality i8* bitcast (void ()* @Personality to i8*) {
+entry:
+  invoke void @f()
+    to label %exit unwind label %cleanup.pad
+cleanup.pad:
+  ; CHECK: %cleanup = cleanuppad []
+  ; CHECK-NEXT: call void @f()
+  ; CHECK-NEXT: unreachable
+  %cleanup = cleanuppad []
+  invoke void @f()
+    to label %cleanup.ret unwind label %cleanup.end
+cleanup.ret:
+  ; This cleanupret should be rewritten to unreachable,
+  ; and merged into the pred block.
+  cleanupret %cleanup unwind label %unreachable.unwind
+cleanup.end:
+  ; This cleanupendpad should be rewritten to unreachable,
+  ; causing the invoke to be rewritten to a call.
+  cleanupendpad %cleanup unwind label %unreachable.unwind
+exit:
+  ret void
+unreachable.unwind:
+  cleanuppad []
+  unreachable
+}
+
+; CHECK-LABEL: define void @test4()
+define void @test4() personality i8* bitcast (void ()* @Personality to i8*) {
+entry:
+  invoke void @f()
+    to label %exit unwind label %terminate.pad
+terminate.pad:
+  ; CHECK: terminatepad [] unwind to caller
+  terminatepad [] unwind label %unreachable.unwind
+exit:
+  ret void
+unreachable.unwind:
+  cleanuppad []
+  unreachable
+}