From 67e85f751c5dfcdfe28a711791535a38cc5e3f60 Mon Sep 17 00:00:00 2001 From: Frederic Riss Date: Wed, 17 Feb 2016 18:51:27 +0000 Subject: [PATCH] [ObjCARC] Handle ARCInstKind::ClaimRV in OptimizeIndividualCalls. When support for objc_unsafeClaimAutoreleasedReturnValue has been added to the ARC optimizer in r258970, one case was missed which would lead the optimizer to execute an llvm_unreachable. In this case, just handle ClaimRV in the same way we handle RetainRV. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@261134 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/ObjCARC/ObjCARCOpts.cpp | 1 + test/Transforms/ObjCARC/unsafe-claim-rv.ll | 47 ++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 test/Transforms/ObjCARC/unsafe-claim-rv.ll diff --git a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index f0ee6e2be48..39e99a00b0c 100644 --- a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -889,6 +889,7 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) { Inst->getParent(), Inst, DependingInstructions, Visited, PA); break; + case ARCInstKind::ClaimRV: case ARCInstKind::RetainRV: case ARCInstKind::AutoreleaseRV: // Don't move these; the RV optimization depends on the autoreleaseRV diff --git a/test/Transforms/ObjCARC/unsafe-claim-rv.ll b/test/Transforms/ObjCARC/unsafe-claim-rv.ll new file mode 100644 index 00000000000..addd0c8f973 --- /dev/null +++ b/test/Transforms/ObjCARC/unsafe-claim-rv.ll @@ -0,0 +1,47 @@ +; RUN: opt -objc-arc -S < %s | FileCheck %s + +; Generated by compiling: +; +; id baz(void *X) { return (__bridge_transfer id)X; } +; +; void foo(id X) { +; void *Y = 0; +; if (X) +; Y = (__bridge_retained void *)X; +; baz(Y); +; } +; +; clang -x objective-c -mllvm -enable-objc-arc-opts=0 -fobjc-arc -S -emit-llvm test.m +; +; And then hand-reduced further. + +declare i8* @objc_autoreleaseReturnValue(i8*) +declare i8* @objc_unsafeClaimAutoreleasedReturnValue(i8*) +declare i8* @objc_retain(i8*) +declare void @objc_release(i8*) + +define void @foo(i8* %X) { +entry: + %0 = tail call i8* @objc_retain(i8* %X) + %tobool = icmp eq i8* %0, null + br i1 %tobool, label %if.end, label %if.then + +if.then: ; preds = %entry + %1 = tail call i8* @objc_retain(i8* nonnull %0) + br label %if.end + +if.end: ; preds = %if.then, %entry + %Y.0 = phi i8* [ %1, %if.then ], [ null, %entry ] + %2 = tail call i8* @objc_autoreleaseReturnValue(i8* %Y.0) + %3 = tail call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* %2) + tail call void @objc_release(i8* %0) + ret void +} + +; CHECK: if.then +; CHECK: tail call i8* @objc_retain +; CHECK-NEXT: call i8* @objc_autorelease +; CHECK: %Y.0 = phi +; CHECK-NEXT: tail call i8* @objc_unsafeClaimAutoreleasedReturnValue(i8* %Y.0) +; CHECK-NEXT: tail call void @objc_release + -- 2.11.0