From c72d3be38915728142d13f982eeef218e42f21aa Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 23 Jul 2012 19:27:31 +0000 Subject: [PATCH] An objc_retain can serve as a may-use for a different pointer. rdar://11931823. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160637 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/ObjCARC.cpp | 5 ++++- test/Transforms/ObjCARC/basic.ll | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/lib/Transforms/Scalar/ObjCARC.cpp b/lib/Transforms/Scalar/ObjCARC.cpp index 64f71d380a8..3222f2083b9 100644 --- a/lib/Transforms/Scalar/ObjCARC.cpp +++ b/lib/Transforms/Scalar/ObjCARC.cpp @@ -2829,7 +2829,10 @@ ObjCARCOpt::VisitInstructionTopDown(Instruction *Inst, } S.IncrementNestCount(); - return NestingDetected; + + // A retain can be a potential use; procede to the generic checking + // code below. + break; } case IC_Release: { Arg = GetObjCArg(Inst); diff --git a/test/Transforms/ObjCARC/basic.ll b/test/Transforms/ObjCARC/basic.ll index ba2f778a28e..d9bb3f25bd7 100644 --- a/test/Transforms/ObjCARC/basic.ll +++ b/test/Transforms/ObjCARC/basic.ll @@ -1871,6 +1871,30 @@ return: ; preds = %if.then, %entry ret i8* %retval } +; An objc_retain can serve as a may-use for a different pointer. +; rdar://11931823 + +; CHECK: define void @test66( +; CHECK: %tmp7 = tail call i8* @objc_retain(i8* %cond) nounwind +; CHECK: tail call void @objc_release(i8* %cond) nounwind +; CHECK: } +define void @test66(i8* %tmp5, i8* %bar, i1 %tobool, i1 %tobool1, i8* %call) { +entry: + br i1 %tobool, label %cond.true, label %cond.end + +cond.true: + br label %cond.end + +cond.end: ; preds = %cond.true, %entry + %cond = phi i8* [ %tmp5, %cond.true ], [ %call, %entry ] + %tmp7 = tail call i8* @objc_retain(i8* %cond) nounwind + tail call void @objc_release(i8* %call) nounwind + %tmp8 = select i1 %tobool1, i8* %cond, i8* %bar + %tmp9 = tail call i8* @objc_retain(i8* %tmp8) nounwind + tail call void @objc_release(i8* %cond) nounwind + ret void +} + declare void @bar(i32 ()*) ; A few real-world testcases.