summaryrefslogtreecommitdiff
path: root/test/Transforms/Inline
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-06-09 20:06:24 +0000
committerJohn McCall <rjmccall@apple.com>2011-06-09 20:06:24 +0000
commit1dd94bbfa1269b1144a87f5fe9dbc04869f858b4 (patch)
tree9180e95db484d1369153fa77ae8726aef4812c65 /test/Transforms/Inline
parent54c256233f8dcd29406d5fe6f8a5be79a826cef3 (diff)
downloadllvm-1dd94bbfa1269b1144a87f5fe9dbc04869f858b4.tar.gz
llvm-1dd94bbfa1269b1144a87f5fe9dbc04869f858b4.tar.bz2
llvm-1dd94bbfa1269b1144a87f5fe9dbc04869f858b4.tar.xz
SplitCriticalEdge can sometimes split the edge from an invoke to a landing
pad, separating the exception and selector calls from the new lpad. Teaching it not to do that, or to properly adjust the CFG afterwards, is out of scope because it would require the other edges to the landing pad to be split as well (effectively). Instead, just recover from the most likely cases during inlining. The best long-term solution is to change the exception representation and commit to either requiring or not requiring the more complex edge-splitting logic; this is just a shorter-term hack. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132799 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Transforms/Inline')
-rw-r--r--test/Transforms/Inline/inline_invoke.ll93
1 files changed, 92 insertions, 1 deletions
diff --git a/test/Transforms/Inline/inline_invoke.ll b/test/Transforms/Inline/inline_invoke.ll
index 5f657387c2..2a1b8836c7 100644
--- a/test/Transforms/Inline/inline_invoke.ll
+++ b/test/Transforms/Inline/inline_invoke.ll
@@ -16,6 +16,8 @@ declare void @_ZN1AD1Ev(%struct.A*)
declare void @use(i32) nounwind
+declare void @opaque()
+
declare i8* @llvm.eh.exception() nounwind readonly
declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind
@@ -217,8 +219,8 @@ eh.resume:
; CHECK: call void @llvm.eh.resume(i8* [[EXNJ1]], i32 [[SELJ1]])
-;; Test 2 - Don't make invalid IR for inlines into landing pads without eh.exception calls
+;; Test 2 - Don't make invalid IR for inlines into landing pads without eh.exception calls
define void @test2_out() uwtable ssp {
entry:
invoke void @test0_in()
@@ -243,3 +245,92 @@ lpad:
; CHECK-NEXT: unwind label %[[LPAD2]]
; CHECK: invoke void @_ZN1AD1Ev(%struct.A* [[A]])
; CHECK-NEXT: unwind label %[[LPAD]]
+
+
+;; Test 3 - Deal correctly with split unwind edges.
+define void @test3_out() uwtable ssp {
+entry:
+ invoke void @test0_in()
+ to label %ret unwind label %lpad
+
+ret:
+ ret void
+
+lpad:
+ br label %lpad.cont
+
+lpad.cont:
+ %exn = call i8* @llvm.eh.exception() nounwind
+ %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*)) nounwind
+ call void @_ZSt9terminatev()
+ unreachable
+}
+
+; CHECK: define void @test3_out()
+; CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{%.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0, i8* bitcast (i8** @_ZTIi to i8*))
+; CHECK-NEXT: invoke void @_ZN1AD1Ev(
+; CHECK-NEXT: to label %[[L:[^\s]+]] unwind
+; CHECK: [[L]]:
+; CHECK-NEXT: br label %[[JOIN:[^\s]+]]
+; CHECK: [[JOIN]]:
+; CHECK-NEXT: phi
+; CHECK-NEXT: phi
+; CHECK-NEXT: br label %lpad.cont
+; CHECK: lpad.cont:
+; CHECK-NEXT: call void @_ZSt9terminatev()
+
+
+;; Test 4 - Split unwind edges with a dominance problem
+define void @test4_out() uwtable ssp {
+entry:
+ invoke void @test0_in()
+ to label %cont unwind label %lpad.crit
+
+cont:
+ invoke void @opaque()
+ to label %ret unwind label %lpad
+
+ret:
+ ret void
+
+lpad.crit:
+ call void @opaque() nounwind
+ br label %lpad
+
+lpad:
+ %phi = phi i32 [ 0, %lpad.crit ], [ 1, %cont ]
+ %exn = call i8* @llvm.eh.exception() nounwind
+ %eh.selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*)) nounwind
+ call void @use(i32 %phi)
+ call void @_ZSt9terminatev()
+ unreachable
+}
+
+; CHECK: define void @test4_out()
+; CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{%.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0, i8* bitcast (i8** @_ZTIi to i8*))
+; CHECK-NEXT: invoke void @_ZN1AD1Ev(
+; CHECK-NEXT: to label %[[L:[^\s]+]] unwind
+; CHECK: [[L]]:
+; CHECK-NEXT: br label %[[JOIN:[^\s]+]]
+; CHECK: invoke void @opaque()
+; CHECK-NEXT: unwind label %lpad
+; CHECK: lpad.crit:
+; CHECK-NEXT: call i8* @llvm.eh.exception()
+; CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %4, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*))
+; CHECK-NEXT: br label %[[JOIN]]
+; CHECK: [[JOIN]]:
+; CHECK-NEXT: phi i8*
+; CHECK-NEXT: phi i32
+; CHECK-NEXT: call void @opaque() nounwind
+; CHECK-NEXT: br label %[[FIX:[^\s]+]]
+; CHECK: lpad:
+; CHECK-NEXT: [[T0:%.*]] = phi i32 [ 1, %cont ]
+; CHECK-NEXT: call i8* @llvm.eh.exception() nounwind
+; CHECK-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*))
+; CHECK-NEXT: br label %[[FIX]]
+; CHECK: [[FIX]]:
+; CHECK-NEXT: [[T1:%.*]] = phi i32 [ [[T0]], %lpad ], [ 0, %[[JOIN]] ]
+; CHECK-NEXT: phi i8*
+; CHECK-NEXT: phi i32
+; CHECK-NEXT: call void @use(i32 [[T1]])
+; CHECK-NEXT: call void @_ZSt9terminatev()