brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.5 KiB · a792b8e Raw
225 lines · plain
1; RUN: opt -S -passes=objc-arc < %s | FileCheck %s2 3declare ptr @llvm.objc.retain(ptr)4declare void @llvm.objc.release(ptr)5declare ptr @llvm.objc.retainAutoreleasedReturnValue(ptr)6declare ptr @objc_msgSend(ptr, ptr, ...)7declare void @use_pointer(ptr)8declare void @callee()9declare ptr @returner()10 11; ARCOpt shouldn't try to move the releases to the block containing the invoke.12 13; CHECK-LABEL: define void @test0(14; CHECK: invoke.cont:15; CHECK:   call void @llvm.objc.release(ptr %zipFile) [[NUW:#[0-9]+]], !clang.imprecise_release !016; CHECK:   ret void17; CHECK: lpad:18; CHECK:   call void @llvm.objc.release(ptr %zipFile) [[NUW]], !clang.imprecise_release !019; CHECK:   ret void20; CHECK-NEXT: }21define void @test0(ptr %zipFile) personality ptr @__gxx_personality_v0 {22entry:23  call ptr @llvm.objc.retain(ptr %zipFile) nounwind24  call void @use_pointer(ptr %zipFile)25  invoke void @objc_msgSend(ptr %zipFile) 26          to label %invoke.cont unwind label %lpad27 28invoke.cont:                                      ; preds = %entry29  call void @llvm.objc.release(ptr %zipFile) nounwind, !clang.imprecise_release !030  ret void31 32lpad:                                             ; preds = %entry33  %exn = landingpad {ptr, i32}34           cleanup35  call void @llvm.objc.release(ptr %zipFile) nounwind, !clang.imprecise_release !036  ret void37}38 39; ARCOpt should move the release before the callee calls.40 41; CHECK-LABEL: define void @test1(42; CHECK: invoke.cont:43; CHECK:   call void @llvm.objc.release(ptr %zipFile) [[NUW]], !clang.imprecise_release !044; CHECK:   call void @callee()45; CHECK:   br label %done46; CHECK: lpad:47; CHECK:   call void @llvm.objc.release(ptr %zipFile) [[NUW]], !clang.imprecise_release !048; CHECK:   call void @callee()49; CHECK:   br label %done50; CHECK: done:51; CHECK-NEXT: ret void52; CHECK-NEXT: }53define void @test1(ptr %zipFile) personality ptr @__gxx_personality_v0 {54entry:55  call ptr @llvm.objc.retain(ptr %zipFile) nounwind56  call void @use_pointer(ptr %zipFile)57  invoke void @objc_msgSend(ptr %zipFile)58          to label %invoke.cont unwind label %lpad59 60invoke.cont:                                      ; preds = %entry61  call void @callee()62  br label %done63 64lpad:                                             ; preds = %entry65  %exn = landingpad {ptr, i32}66           cleanup67  call void @callee()68  br label %done69 70done:71  call void @llvm.objc.release(ptr %zipFile) nounwind, !clang.imprecise_release !072  ret void73}74 75; The optimizer should ignore invoke unwind paths consistently.76; PR1226577 78; CHECK: define void @test2() personality ptr @__objc_personality_v0 {79; CHECK: invoke.cont:80; CHECK-NEXT: call ptr @llvm.objc.retain81; CHECK-NOT: @llvm.objc.r82; CHECK: finally.cont:83; CHECK-NEXT: call void @llvm.objc.release84; CHECK-NOT: @objc85; CHECK: finally.rethrow:86; CHECK-NOT: @objc87; CHECK: }88define void @test2() personality ptr @__objc_personality_v0 {89entry:90  %call = invoke ptr @objc_msgSend()91          to label %invoke.cont unwind label %finally.rethrow, !clang.arc.no_objc_arc_exceptions !092 93invoke.cont:                                      ; preds = %entry94  %tmp1 = tail call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %call) nounwind95  call void @objc_msgSend(), !clang.arc.no_objc_arc_exceptions !096  invoke void @use_pointer(ptr %call)97          to label %finally.cont unwind label %finally.rethrow, !clang.arc.no_objc_arc_exceptions !098 99finally.cont:                                     ; preds = %invoke.cont100  tail call void @llvm.objc.release(ptr %call) nounwind, !clang.imprecise_release !0101  ret void102 103finally.rethrow:                                  ; preds = %invoke.cont, %entry104  %tmp2 = landingpad { ptr, i32 }105          catch ptr null106  unreachable107}108 109; Don't try to place code on invoke critical edges.110 111; CHECK-LABEL: define void @test3(112; CHECK: if.end:113; CHECK-NEXT: call void @llvm.objc.release(ptr %p) [[NUW]]114; CHECK-NEXT: ret void115; CHECK-NEXT: }116define void @test3(ptr %p, i1 %b) personality ptr @__objc_personality_v0 {117entry:118  %0 = call ptr @llvm.objc.retain(ptr %p)119  call void @callee()120  br i1 %b, label %if.else, label %if.then121 122if.then:123  invoke void @use_pointer(ptr %p)124          to label %if.end unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0125 126if.else:127  invoke void @use_pointer(ptr %p)128          to label %if.end unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0129 130lpad:131  %r = landingpad { ptr, i32 }132       cleanup133  ret void134 135if.end:136  call void @llvm.objc.release(ptr %p)137  ret void138}139 140; Like test3, but with ARC-relevant exception handling.141 142; CHECK-LABEL: define void @test4(143; CHECK: lpad:144; CHECK-NEXT: %r = landingpad { ptr, i32 }145; CHECK-NEXT: cleanup146; CHECK-NEXT: call void @llvm.objc.release(ptr %p) [[NUW]]147; CHECK-NEXT: ret void148; CHECK: if.end:149; CHECK-NEXT: call void @llvm.objc.release(ptr %p) [[NUW]]150; CHECK-NEXT: ret void151; CHECK-NEXT: }152define void @test4(ptr %p, i1 %b) personality ptr @__objc_personality_v0 {153entry:154  %0 = call ptr @llvm.objc.retain(ptr %p)155  call void @callee()156  br i1 %b, label %if.else, label %if.then157 158if.then:159  invoke void @use_pointer(ptr %p)160          to label %if.end unwind label %lpad161 162if.else:163  invoke void @use_pointer(ptr %p)164          to label %if.end unwind label %lpad165 166lpad:167  %r = landingpad { ptr, i32 }168       cleanup169  call void @llvm.objc.release(ptr %p)170  ret void171 172if.end:173  call void @llvm.objc.release(ptr %p)174  ret void175}176 177; Don't turn the retainAutoreleaseReturnValue into retain, because it's178; for an invoke which we can assume codegen will put immediately prior.179 180; CHECK-LABEL: define void @test5(181; CHECK: call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %z)182; CHECK: }183define void @test5() personality ptr @__objc_personality_v0 {184entry:185  %z = invoke ptr @returner()186          to label %if.end unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0187 188lpad:189  %r13 = landingpad { ptr, i32 }190          cleanup191  ret void192 193if.end:194  call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %z)195  ret void196}197 198; Like test5, but there's intervening code.199 200; CHECK-LABEL: define void @test6(201; CHECK: call ptr @llvm.objc.retain(ptr %z)202; CHECK: }203define void @test6() personality ptr @__objc_personality_v0 {204entry:205  %z = invoke ptr @returner()206          to label %if.end unwind label %lpad, !clang.arc.no_objc_arc_exceptions !0207 208lpad:209  %r13 = landingpad { ptr, i32 }210          cleanup211  ret void212 213if.end:214  call void @callee()215  call ptr @llvm.objc.retainAutoreleasedReturnValue(ptr %z)216  ret void217}218 219declare i32 @__gxx_personality_v0(...)220declare i32 @__objc_personality_v0(...)221 222; CHECK: attributes [[NUW]] = { nounwind }223 224!0 = !{}225