1; RUN: opt -S -objc-arc < %s | FileCheck %s 2 3declare i8* @objc_retain(i8*) 4declare void @objc_release(i8*) 5declare i8* @objc_msgSend(i8*, i8*, ...) 6declare void @use_pointer(i8*) 7declare void @callee() 8 9; ARCOpt shouldn't try to move the releases to the block containing the invoke. 10 11; CHECK: define void @test0( 12; CHECK: invoke.cont: 13; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0 14; CHECK: ret void 15; CHECK: lpad: 16; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0 17; CHECK: ret void 18define void @test0(i8* %zipFile) { 19entry: 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 24 25invoke.cont: ; preds = %entry 26 call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0 27 ret void 28 29lpad: ; preds = %entry 30 %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 31 cleanup 32 call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0 33 ret void 34} 35 36; ARCOpt should move the release before the callee calls. 37 38; CHECK: define void @test1( 39; CHECK: invoke.cont: 40; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0 41; CHECK: call void @callee() 42; CHECK: br label %done 43; CHECK: lpad: 44; CHECK: call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0 45; CHECK: call void @callee() 46; CHECK: br label %done 47; CHECK: done: 48; CHECK-NEXT: ret void 49define void @test1(i8* %zipFile) { 50entry: 51 call i8* @objc_retain(i8* %zipFile) nounwind 52 call void @use_pointer(i8* %zipFile) 53 invoke void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*)*)(i8* %zipFile) 54 to label %invoke.cont unwind label %lpad 55 56invoke.cont: ; preds = %entry 57 call void @callee() 58 br label %done 59 60lpad: ; preds = %entry 61 %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 62 cleanup 63 call void @callee() 64 br label %done 65 66done: 67 call void @objc_release(i8* %zipFile) nounwind, !clang.imprecise_release !0 68 ret void 69} 70 71declare i32 @__gxx_personality_v0(...) 72 73!0 = metadata !{} 74