[llvm] r178922 - An objc_retain can serve as a use for a different pointer.
Michael Gottesman
mgottesman at apple.com
Fri Apr 5 15:54:32 PDT 2013
Author: mgottesman
Date: Fri Apr 5 17:54:32 2013
New Revision: 178922
URL: http://llvm.org/viewvc/llvm-project?rev=178922&view=rev
Log:
An objc_retain can serve as a use for a different pointer.
This is the counterpart to commit r160637, except it performs the action
in the bottomup portion of the data flow analysis.
Modified:
llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
llvm/trunk/test/Transforms/ObjCARC/basic.ll
Modified: llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp?rev=178922&r1=178921&r2=178922&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp Fri Apr 5 17:54:32 2013
@@ -1817,8 +1817,9 @@ ObjCARCOpt::VisitInstructionBottomUp(Ins
case S_Retain:
llvm_unreachable("bottom-up pointer in retain state!");
}
- ANNOTATE_BOTTOMUP(Inst, Arg, OldSeq, S.GetSeq());
- return NestingDetected;
+ ANNOTATE_BOTTOMUP(Inst, Arg, OldSeq, S.GetSeq());
+ // A retain moving bottom up can be a use.
+ break;
}
case IC_AutoreleasepoolPop:
// Conservatively, clear MyStates for all known pointers.
Modified: llvm/trunk/test/Transforms/ObjCARC/basic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ObjCARC/basic.ll?rev=178922&r1=178921&r2=178922&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/ObjCARC/basic.ll (original)
+++ llvm/trunk/test/Transforms/ObjCARC/basic.ll Fri Apr 5 17:54:32 2013
@@ -2607,6 +2607,101 @@ return:
ret i8* %retval
}
+; An objc_retain can serve as a may-use for a different pointer.
+; rdar://11931823
+
+; CHECK: define void @test66a(
+; CHECK: tail call i8* @objc_retain(i8* %cond) [[NUW]]
+; CHECK: tail call void @objc_release(i8* %call) [[NUW]]
+; CHECK: tail call i8* @objc_retain(i8* %tmp8) [[NUW]]
+; CHECK: tail call void @objc_release(i8* %cond) [[NUW]]
+; CHECK: }
+define void @test66a(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
+}
+
+; CHECK: define void @test66b(
+; CHECK: tail call i8* @objc_retain(i8* %cond) [[NUW]]
+; CHECK: tail call void @objc_release(i8* %call) [[NUW]]
+; CHECK: tail call i8* @objc_retain(i8* %tmp8) [[NUW]]
+; CHECK: tail call void @objc_release(i8* %cond) [[NUW]]
+; CHECK: }
+define void @test66b(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, !clang.imprecise_release !0
+ %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
+}
+
+; CHECK: define void @test66c(
+; CHECK: tail call i8* @objc_retain(i8* %cond) [[NUW]]
+; CHECK: tail call void @objc_release(i8* %call) [[NUW]]
+; CHECK: tail call i8* @objc_retain(i8* %tmp8) [[NUW]]
+; CHECK: tail call void @objc_release(i8* %cond) [[NUW]]
+; CHECK: }
+define void @test66c(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, !clang.imprecise_release !0
+ tail call void @objc_release(i8* %cond) nounwind
+ ret void
+}
+
+; CHECK: define void @test66d(
+; CHECK: tail call i8* @objc_retain(i8* %cond) [[NUW]]
+; CHECK: tail call void @objc_release(i8* %call) [[NUW]]
+; CHECK: tail call i8* @objc_retain(i8* %tmp8) [[NUW]]
+; CHECK: tail call void @objc_release(i8* %cond) [[NUW]]
+; CHECK: }
+define void @test66d(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, !clang.imprecise_release !0
+ %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, !clang.imprecise_release !0
+ ret void
+}
+
; A few real-world testcases.
@.str4 = private unnamed_addr constant [33 x i8] c"-[A z] = { %f, %f, { %f, %f } }\0A\00"
More information about the llvm-commits
mailing list