mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-25 20:59:51 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178922 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e7ce2b3f75
commit
e8b3c2e48a
@ -1817,8 +1817,9 @@ ObjCARCOpt::VisitInstructionBottomUp(Instruction *Inst,
|
|||||||
case S_Retain:
|
case S_Retain:
|
||||||
llvm_unreachable("bottom-up pointer in retain state!");
|
llvm_unreachable("bottom-up pointer in retain state!");
|
||||||
}
|
}
|
||||||
ANNOTATE_BOTTOMUP(Inst, Arg, OldSeq, S.GetSeq());
|
ANNOTATE_BOTTOMUP(Inst, Arg, OldSeq, S.GetSeq());
|
||||||
return NestingDetected;
|
// A retain moving bottom up can be a use.
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case IC_AutoreleasepoolPop:
|
case IC_AutoreleasepoolPop:
|
||||||
// Conservatively, clear MyStates for all known pointers.
|
// Conservatively, clear MyStates for all known pointers.
|
||||||
|
@ -2607,6 +2607,101 @@ return: ; preds = %if.then, %entry
|
|||||||
ret i8* %retval
|
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.
|
; A few real-world testcases.
|
||||||
|
|
||||||
@.str4 = private unnamed_addr constant [33 x i8] c"-[A z] = { %f, %f, { %f, %f } }\0A\00"
|
@.str4 = private unnamed_addr constant [33 x i8] c"-[A z] = { %f, %f, { %f, %f } }\0A\00"
|
||||||
|
Loading…
Reference in New Issue
Block a user