diff options
Diffstat (limited to 'test/Transforms/ObjCARC/cfg-hazards.ll')
-rw-r--r-- | test/Transforms/ObjCARC/cfg-hazards.ll | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/test/Transforms/ObjCARC/cfg-hazards.ll b/test/Transforms/ObjCARC/cfg-hazards.ll index 66a7b1b..1519423 100644 --- a/test/Transforms/ObjCARC/cfg-hazards.ll +++ b/test/Transforms/ObjCARC/cfg-hazards.ll @@ -7,6 +7,7 @@ declare void @use_pointer(i8*) declare i8* @objc_retain(i8*) declare void @objc_release(i8*) +declare void @callee() ; CHECK: define void @test0( ; CHECK: call i8* @objc_retain( @@ -83,4 +84,314 @@ for.end: ; preds = %for.body ret void } +; Delete nested retain+release pairs around loops. + +; CHECK: define void @test3(i8* %a) nounwind { +; CHECK-NEXT: entry: +; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind +; CHECK-NEXT: br label %loop +; CHECK-NOT: @objc_ +; CHECK: exit: +; CHECK-NEXT: call void @objc_release(i8* %a) +; CHECK-NEXT: ret void +; CHECK-NEXT: } +define void @test3(i8* %a) nounwind { +entry: + %outer = call i8* @objc_retain(i8* %a) nounwind + %inner = call i8* @objc_retain(i8* %a) nounwind + br label %loop + +loop: + call void @callee() + store i8 0, i8* %a + br i1 undef, label %loop, label %exit + +exit: + call void @objc_release(i8* %a) nounwind + call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 + ret void +} + +; CHECK: define void @test4(i8* %a) nounwind { +; CHECK-NEXT: entry: +; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind +; CHECK-NEXT: br label %loop +; CHECK-NOT: @objc_ +; CHECK: exit: +; CHECK-NEXT: call void @objc_release(i8* %a) +; CHECK-NEXT: ret void +; CHECK-NEXT: } +define void @test4(i8* %a) nounwind { +entry: + %outer = call i8* @objc_retain(i8* %a) nounwind + %inner = call i8* @objc_retain(i8* %a) nounwind + br label %loop + +loop: + br label %more + +more: + call void @callee() + call void @callee() + store i8 0, i8* %a + br i1 undef, label %loop, label %exit + +exit: + call void @objc_release(i8* %a) nounwind + call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 + ret void +} + +; CHECK: define void @test5(i8* %a) nounwind { +; CHECK-NEXT: entry: +; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind +; CHECK-NEXT: call void @callee() +; CHECK-NEXT: br label %loop +; CHECK-NOT: @objc_ +; CHECK: exit: +; CHECK-NEXT: call void @use_pointer(i8* %a) +; CHECK-NEXT: call void @objc_release(i8* %a) +; CHECK-NEXT: ret void +; CHECK-NEXT: } +define void @test5(i8* %a) nounwind { +entry: + %outer = tail call i8* @objc_retain(i8* %a) nounwind + %inner = tail call i8* @objc_retain(i8* %a) nounwind + call void @callee() + br label %loop + +loop: + br i1 undef, label %true, label %more + +true: + br label %more + +more: + br i1 undef, label %exit, label %loop + +exit: + call void @use_pointer(i8* %a) + call void @objc_release(i8* %a) nounwind + call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 + ret void +} + +; CHECK: define void @test6(i8* %a) nounwind { +; CHECK-NEXT: entry: +; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind +; CHECK-NEXT: br label %loop +; CHECK-NOT: @objc_ +; CHECK: exit: +; CHECK-NEXT: call void @use_pointer(i8* %a) +; CHECK-NEXT: call void @objc_release(i8* %a) +; CHECK-NEXT: ret void +; CHECK-NEXT: } +define void @test6(i8* %a) nounwind { +entry: + %outer = tail call i8* @objc_retain(i8* %a) nounwind + %inner = tail call i8* @objc_retain(i8* %a) nounwind + br label %loop + +loop: + br i1 undef, label %true, label %more + +true: + call void @callee() + br label %more + +more: + br i1 undef, label %exit, label %loop + +exit: + call void @use_pointer(i8* %a) + call void @objc_release(i8* %a) nounwind + call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 + ret void +} + +; CHECK: define void @test7(i8* %a) nounwind { +; CHECK-NEXT: entry: +; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind +; CHECK-NEXT: call void @callee() +; CHECK-NEXT: br label %loop +; CHECK-NOT: @objc_ +; CHECK: exit: +; CHECK-NEXT: call void @objc_release(i8* %a) +; CHECK-NEXT: ret void +; CHECK-NEXT: } +define void @test7(i8* %a) nounwind { +entry: + %outer = tail call i8* @objc_retain(i8* %a) nounwind + %inner = tail call i8* @objc_retain(i8* %a) nounwind + call void @callee() + br label %loop + +loop: + br i1 undef, label %true, label %more + +true: + call void @use_pointer(i8* %a) + br label %more + +more: + br i1 undef, label %exit, label %loop + +exit: + call void @objc_release(i8* %a) nounwind + call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 + ret void +} + +; CHECK: define void @test8(i8* %a) nounwind { +; CHECK-NEXT: entry: +; CHECK-NEXT: tail call i8* @objc_retain(i8* %a) nounwind +; CHECK-NEXT: br label %loop +; CHECK-NOT: @objc_ +; CHECK: exit: +; CHECK-NEXT: call void @objc_release(i8* %a) +; CHECK-NEXT: ret void +; CHECK-NEXT: } +define void @test8(i8* %a) nounwind { +entry: + %outer = tail call i8* @objc_retain(i8* %a) nounwind + %inner = tail call i8* @objc_retain(i8* %a) nounwind + br label %loop + +loop: + br i1 undef, label %true, label %more + +true: + call void @callee() + call void @use_pointer(i8* %a) + br label %more + +more: + br i1 undef, label %exit, label %loop + +exit: + call void @objc_release(i8* %a) nounwind + call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 + ret void +} + +; CHECK: define void @test9(i8* %a) nounwind { +; CHECK-NEXT: entry: +; CHECK-NEXT: br label %loop +; CHECK-NOT: @objc_ +; CHECK: exit: +; CHECK-NEXT: ret void +; CHECK-NEXT: } +define void @test9(i8* %a) nounwind { +entry: + %outer = tail call i8* @objc_retain(i8* %a) nounwind + %inner = tail call i8* @objc_retain(i8* %a) nounwind + br label %loop + +loop: + br i1 undef, label %true, label %more + +true: + call void @use_pointer(i8* %a) + br label %more + +more: + br i1 undef, label %exit, label %loop + +exit: + call void @objc_release(i8* %a) nounwind + call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 + ret void +} + +; CHECK: define void @test10(i8* %a) nounwind { +; CHECK-NEXT: entry: +; CHECK-NEXT: br label %loop +; CHECK-NOT: @objc_ +; CHECK: exit: +; CHECK-NEXT: ret void +; CHECK-NEXT: } +define void @test10(i8* %a) nounwind { +entry: + %outer = tail call i8* @objc_retain(i8* %a) nounwind + %inner = tail call i8* @objc_retain(i8* %a) nounwind + br label %loop + +loop: + br i1 undef, label %true, label %more + +true: + call void @callee() + br label %more + +more: + br i1 undef, label %exit, label %loop + +exit: + call void @objc_release(i8* %a) nounwind + call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 + ret void +} + +; CHECK: define void @test11(i8* %a) nounwind { +; CHECK-NEXT: entry: +; CHECK-NEXT: br label %loop +; CHECK-NOT: @objc_ +; CHECK: exit: +; CHECK-NEXT: ret void +; CHECK-NEXT: } +define void @test11(i8* %a) nounwind { +entry: + %outer = tail call i8* @objc_retain(i8* %a) nounwind + %inner = tail call i8* @objc_retain(i8* %a) nounwind + br label %loop + +loop: + br i1 undef, label %true, label %more + +true: + br label %more + +more: + br i1 undef, label %exit, label %loop + +exit: + call void @objc_release(i8* %a) nounwind + call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 + ret void +} + +; Don't delete anything if they're not balanced. + +; CHECK: define void @test12(i8* %a) nounwind { +; CHECK-NEXT: entry: +; CHECK-NEXT: %outer = tail call i8* @objc_retain(i8* %a) nounwind +; CHECK-NEXT: %inner = tail call i8* @objc_retain(i8* %a) nounwind +; CHECK-NEXT: br label %loop +; CHECK-NOT: @objc_ +; CHECK: exit: +; CHECK-NEXT: call void @objc_release(i8* %a) nounwind +; CHECK-NEXT: call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 +; CHECK-NEXT: ret void +; CHECK-NEXT: } +define void @test12(i8* %a) nounwind { +entry: + %outer = tail call i8* @objc_retain(i8* %a) nounwind + %inner = tail call i8* @objc_retain(i8* %a) nounwind + br label %loop + +loop: + br i1 undef, label %true, label %more + +true: + ret void + +more: + br i1 undef, label %exit, label %loop + +exit: + call void @objc_release(i8* %a) nounwind + call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 + ret void +} + !0 = metadata !{} |