From 4bd9c52fadd800122f3b3756c9621da387496d77 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Mon, 16 Oct 2017 16:46:59 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315914 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/ObjCARC/ObjCARCOpts.cpp | 11 ++++++++--- test/Transforms/ObjCARC/basic.ll | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index 8c0a90843ef..6692d950da2 100644 --- a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -808,9 +808,14 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) { // 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 - // are no relevant side effects between the PHI and the call, the call - // could be pushed up to just those paths with non-null incoming values. - // For now, don't bother splitting critical edges for this. + // are no relevant side effects between the PHI and the call, and the call + // is not a release that doesn't have the clang.imprecise_release tag, the + // 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, 4> Worklist; Worklist.push_back(std::make_pair(Inst, Arg)); do { diff --git a/test/Transforms/ObjCARC/basic.ll b/test/Transforms/ObjCARC/basic.ll index cecaa3f2b4d..70b83b93138 100644 --- a/test/Transforms/ObjCARC/basic.ll +++ b/test/Transforms/ObjCARC/basic.ll @@ -1342,6 +1342,26 @@ A: br label %C B: 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: %h = phi double* [ null, %A ], [ %p, %B ] %c = bitcast double* %h to i8* -- 2.50.1