forked from OSchip/llvm-project
[ObjCARC] Do not move a release that has the clang.imprecise_release tag
above PHI instructions. ARC optimizer has an optimization that moves a call to an ObjC runtime function above a phi instruction when the phi has a null operand and is an argument passed to the function call. This optimization should not kick in when the runtime function is an objc_release that releases an object with precise lifetime semantics. rdar://problem/34959669 llvm-svn: 315914
This commit is contained in:
parent
a4b89ed0b7
commit
e8c1a54c07
|
@ -808,9 +808,14 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
|
||||||
|
|
||||||
// If Arg is a PHI, and one or more incoming values to the
|
// If Arg is a PHI, and one or more incoming values to the
|
||||||
// PHI are null, and the call is control-equivalent to the PHI, and there
|
// PHI are null, and the call is control-equivalent to the PHI, and there
|
||||||
// are no relevant side effects between the PHI and the call, the call
|
// are no relevant side effects between the PHI and the call, and the call
|
||||||
// could be pushed up to just those paths with non-null incoming values.
|
// is not a release that doesn't have the clang.imprecise_release tag, the
|
||||||
// For now, don't bother splitting critical edges for this.
|
// call could be pushed up to just those paths with non-null incoming
|
||||||
|
// values. For now, don't bother splitting critical edges for this.
|
||||||
|
if (Class == ARCInstKind::Release &&
|
||||||
|
!Inst->getMetadata(MDKindCache.get(ARCMDKindID::ImpreciseRelease)))
|
||||||
|
continue;
|
||||||
|
|
||||||
SmallVector<std::pair<Instruction *, const Value *>, 4> Worklist;
|
SmallVector<std::pair<Instruction *, const Value *>, 4> Worklist;
|
||||||
Worklist.push_back(std::make_pair(Inst, Arg));
|
Worklist.push_back(std::make_pair(Inst, Arg));
|
||||||
do {
|
do {
|
||||||
|
|
|
@ -1342,6 +1342,26 @@ A:
|
||||||
br label %C
|
br label %C
|
||||||
B:
|
B:
|
||||||
br label %C
|
br label %C
|
||||||
|
C:
|
||||||
|
%h = phi double* [ null, %A ], [ %p, %B ]
|
||||||
|
%c = bitcast double* %h to i8*
|
||||||
|
call void @objc_release(i8* %c), !clang.imprecise_release !0
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Do not move an objc_release that doesn't have the clang.imprecise_release tag.
|
||||||
|
|
||||||
|
; CHECK-LABEL: define void @test22_precise(
|
||||||
|
; CHECK: %[[P0:.*]] = phi double*
|
||||||
|
; CHECK: %[[V0:.*]] = bitcast double* %[[P0]] to i8*
|
||||||
|
; CHECK: call void @objc_release(i8* %[[V0]])
|
||||||
|
; CHECK: ret void
|
||||||
|
define void @test22_precise(double* %p, i1 %a) {
|
||||||
|
br i1 %a, label %A, label %B
|
||||||
|
A:
|
||||||
|
br label %C
|
||||||
|
B:
|
||||||
|
br label %C
|
||||||
C:
|
C:
|
||||||
%h = phi double* [ null, %A ], [ %p, %B ]
|
%h = phi double* [ null, %A ], [ %p, %B ]
|
||||||
%c = bitcast double* %h to i8*
|
%c = bitcast double* %h to i8*
|
||||||
|
|
Loading…
Reference in New Issue