1 ; RUN: opt -S -objc-arc < %s | FileCheck %s
3 declare i8* @objc_retain(i8*)
4 declare void @objc_release(i8*)
5 declare i8* @objc_msgSend(i8*, i8*, ...)
6 declare void @use_pointer(i8*)
9 ; ARCOpt shouldn't try to move the releases to the block containing the invoke.
11 ; CHECK: define void @test0(
13 ; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
16 ; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
18 define void @test0(i8* %zipFile) {
20 call i8* @objc_retain(i8* %zipFile) nounwind
21 call void @use_pointer(i8* %zipFile)
22 invoke void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*)*)(i8* %zipFile)
23 to label %invoke.cont unwind label %lpad
25 invoke.cont: ; preds = %entry
26 call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
29 lpad: ; preds = %entry
30 call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
34 ; ARCOpt should move the release before the callee calls.
36 ; CHECK: define void @test1(
38 ; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
39 ; CHECK: call void @callee()
40 ; CHECK: br label %done
42 ; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0
43 ; CHECK: call void @callee()
44 ; CHECK: br label %done
46 ; CHECK-NEXT: ret void
47 define void @test1(i8* %zipFile) {
49 call i8* @objc_retain(i8* %zipFile) nounwind
50 call void @use_pointer(i8* %zipFile)
51 invoke void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*)*)(i8* %zipFile)
52 to label %invoke.cont unwind label %lpad
54 invoke.cont: ; preds = %entry
58 lpad: ; preds = %entry
63 call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0