summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2012-03-23 17:47:54 +0000
committerDan Gohman <gohman@apple.com>2012-03-23 17:47:54 +0000
commitfbab4a8c8a142502b7cdeb7112366f8560a94cec (patch)
tree05a89aa34493a306669ab20028d3b135d58383a8 /test
parent8e1fc56b2496270d1d6040cb648eef5d5aeb6079 (diff)
downloadllvm-fbab4a8c8a142502b7cdeb7112366f8560a94cec.tar.gz
llvm-fbab4a8c8a142502b7cdeb7112366f8560a94cec.tar.bz2
llvm-fbab4a8c8a142502b7cdeb7112366f8560a94cec.tar.xz
It's not possible to insert code immediately after an invoke in the
same basic block, and it's not safe to insert code in the successor blocks if the edges are critical edges. Splitting those edges is possible, but undesirable, especially on the unwind side. Instead, make the bottom-up code motion to consider invokes to be part of their successor blocks, rather than part of their parent blocks, so that it doesn't push code past them and onto the edges. This fixes PR12307. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153343 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/Transforms/ObjCARC/invoke.ll66
1 files changed, 66 insertions, 0 deletions
diff --git a/test/Transforms/ObjCARC/invoke.ll b/test/Transforms/ObjCARC/invoke.ll
index 9e2620960e..a852c4e4fb 100644
--- a/test/Transforms/ObjCARC/invoke.ll
+++ b/test/Transforms/ObjCARC/invoke.ll
@@ -103,6 +103,72 @@ finally.rethrow: ; preds = %invoke.cont, %entry
unreachable
}
+; Don't try to place code on invoke critical edges.
+
+; CHECK: define void @test3(
+; CHECK: if.end:
+; CHECK-NEXT: call void @objc_release(i8* %p) nounwind
+; CHECK-NEXT: ret void
+define void @test3(i8* %p, i1 %b) {
+entry:
+ %0 = call i8* @objc_retain(i8* %p)
+ call void @callee()
+ br i1 %b, label %if.else, label %if.then
+
+if.then:
+ invoke void @use_pointer(i8* %p)
+ to label %if.end unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0
+
+if.else:
+ invoke void @use_pointer(i8* %p)
+ to label %if.end unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0
+
+lpad:
+ %r = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*)
+ cleanup
+ ret void
+
+if.end:
+ call void @objc_release(i8* %p)
+ ret void
+}
+
+; Like test3, but with ARC-relevant exception handling.
+
+; CHECK: define void @test4(
+; CHECK: lpad:
+; CHECK-NEXT: %r = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*)
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: call void @objc_release(i8* %p) nounwind
+; CHECK-NEXT: ret void
+; CHECK: if.end:
+; CHECK-NEXT: call void @objc_release(i8* %p) nounwind
+; CHECK-NEXT: ret void
+define void @test4(i8* %p, i1 %b) {
+entry:
+ %0 = call i8* @objc_retain(i8* %p)
+ call void @callee()
+ br i1 %b, label %if.else, label %if.then
+
+if.then:
+ invoke void @use_pointer(i8* %p)
+ to label %if.end unwind label %lpad
+
+if.else:
+ invoke void @use_pointer(i8* %p)
+ to label %if.end unwind label %lpad
+
+lpad:
+ %r = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__objc_personality_v0 to i8*)
+ cleanup
+ call void @objc_release(i8* %p)
+ ret void
+
+if.end:
+ call void @objc_release(i8* %p)
+ ret void
+}
+
declare i32 @__gxx_personality_v0(...)
declare i32 @__objc_personality_v0(...)