X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=test%2FTransforms%2FObjCARC%2Fcfg-hazards.ll;h=61e5a3b1dccb9e1a58cc27ffc752e31b7ea347fb;hb=b55dcfe47fbbcfc1dccd07cb27c02b9a86533d05;hp=899298b5967e46c492ab016a840bdcc4719e1f65;hpb=351b7a10e2560a835759748c58da09e53207b39d;p=oota-llvm.git diff --git a/test/Transforms/ObjCARC/cfg-hazards.ll b/test/Transforms/ObjCARC/cfg-hazards.ll index 899298b5967..61e5a3b1dcc 100644 --- a/test/Transforms/ObjCARC/cfg-hazards.ll +++ b/test/Transforms/ObjCARC/cfg-hazards.ll @@ -8,8 +8,9 @@ declare void @use_pointer(i8*) declare i8* @objc_retain(i8*) declare void @objc_release(i8*) declare void @callee() +declare void @block_callee(void ()*) -; CHECK: define void @test0( +; CHECK-LABEL: define void @test0( ; CHECK: call i8* @objc_retain( ; CHECK: for.body: ; CHECK-NOT: @objc @@ -34,7 +35,7 @@ for.end: ; preds = %for.body ret void } -; CHECK: define void @test1( +; CHECK-LABEL: define void @test1( ; CHECK: call i8* @objc_retain( ; CHECK: for.body: ; CHECK-NOT: @objc @@ -59,7 +60,7 @@ for.end: ; preds = %for.body ret void } -; CHECK: define void @test2( +; CHECK-LABEL: define void @test2( ; CHECK: call i8* @objc_retain( ; CHECK: for.body: ; CHECK-NOT: @objc @@ -394,6 +395,41 @@ exit: ret void } +; Do not improperly pair retains in a for loop with releases outside of a for +; loop when the proper pairing is disguised by a separate provenance represented +; by an alloca. +; rdar://12969722 + +; CHECK: define void @test13(i8* %a) [[NUW]] { +; CHECK: entry: +; CHECK: tail call i8* @objc_retain(i8* %a) [[NUW]] +; CHECK: loop: +; CHECK: tail call i8* @objc_retain(i8* %a) [[NUW]] +; CHECK: call void @block_callee +; CHECK: call void @objc_release(i8* %reloaded_a) [[NUW]] +; CHECK: exit: +; CHECK: call void @objc_release(i8* %a) [[NUW]] +; CHECK: } +define void @test13(i8* %a) nounwind { +entry: + %block = alloca i8* + %a1 = tail call i8* @objc_retain(i8* %a) nounwind + br label %loop + +loop: + %a2 = tail call i8* @objc_retain(i8* %a) nounwind + store i8* %a, i8** %block, align 8 + %casted_block = bitcast i8** %block to void ()* + call void @block_callee(void ()* %casted_block) + %reloaded_a = load i8** %block, align 8 + call void @objc_release(i8* %reloaded_a) nounwind, !clang.imprecise_release !0 + br i1 undef, label %loop, label %exit + +exit: + call void @objc_release(i8* %a) nounwind, !clang.imprecise_release !0 + ret void +} + ; CHECK: attributes [[NUW]] = { nounwind } !0 = metadata !{}