]> granicus.if.org Git - llvm/commitdiff
[ObjCARC] Do not move a release that has the clang.imprecise_release tag
authorAkira Hatanaka <ahatanaka@apple.com>
Mon, 16 Oct 2017 16:46:59 +0000 (16:46 +0000)
committerAkira Hatanaka <ahatanaka@apple.com>
Mon, 16 Oct 2017 16:46:59 +0000 (16:46 +0000)
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
test/Transforms/ObjCARC/basic.ll

index 8c0a90843ef4e64a483edc7a66b558bb444ca9d3..6692d950da2ad804c3d1106bc87d57e31c6bf0a2 100644 (file)
@@ -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<std::pair<Instruction *, const Value *>, 4> Worklist;
     Worklist.push_back(std::make_pair(Inst, Arg));
     do {
index cecaa3f2b4d6811e69c52e35c8664e59f676c31c..70b83b9313865e3a02ca2e5e8d48a8d4fee447e9 100644 (file)
@@ -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*