[clang] de1966e - Revert "[ObjC][ARC] Use operand bundle 'clang.arc.rv' instead of explicitly"
Nico Weber via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 9 08:06:55 PST 2021
Author: Nico Weber
Date: 2021-02-09T11:06:32-05:00
New Revision: de1966e5427985163f8e816834b3a0564b5e24cd
URL: https://github.com/llvm/llvm-project/commit/de1966e5427985163f8e816834b3a0564b5e24cd
DIFF: https://github.com/llvm/llvm-project/commit/de1966e5427985163f8e816834b3a0564b5e24cd.diff
LOG: Revert "[ObjC][ARC] Use operand bundle 'clang.arc.rv' instead of explicitly"
This reverts commit 4a64d8fe392449b205e59031aad5424968cf7446.
Makes clang crash when buildling trivial iOS programs, see comment
after https://reviews.llvm.org/D92808#2551401
Added:
llvm/test/Transforms/TailCallElim/deopt-bundle.ll
Modified:
clang/lib/CodeGen/CGObjC.cpp
clang/lib/CodeGen/CodeGenFunction.h
clang/lib/CodeGen/CodeGenModule.h
clang/test/CodeGenObjC/arc-unsafeclaim.m
llvm/docs/LangRef.rst
llvm/include/llvm/IR/InstrTypes.h
llvm/include/llvm/IR/Intrinsics.td
llvm/include/llvm/IR/LLVMContext.h
llvm/lib/Analysis/ObjCARCInstKind.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/lib/IR/Instructions.cpp
llvm/lib/IR/LLVMContext.cpp
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h
llvm/lib/Transforms/ObjCARC/ObjCARC.cpp
llvm/lib/Transforms/ObjCARC/ObjCARC.h
llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
llvm/lib/Transforms/ObjCARC/PtrState.cpp
llvm/lib/Transforms/ObjCARC/PtrState.h
llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp
llvm/lib/Transforms/Utils/InlineFunction.cpp
llvm/test/Bitcode/operand-bundles-bc-analyzer.ll
llvm/test/CodeGen/AArch64/call-rv-marker.ll
llvm/test/Transforms/DeadArgElim/deadretval.ll
llvm/test/Transforms/ObjCARC/contract-marker-funclet.ll
llvm/test/Transforms/ObjCARC/contract.ll
llvm/test/Transforms/ObjCARC/intrinsic-use.ll
llvm/test/Transforms/ObjCARC/rv.ll
Removed:
clang/test/CodeGenObjC/arc-rv-attr.m
llvm/include/llvm/Analysis/ObjCARCUtil.h
llvm/test/Transforms/Inline/inline-retainRV-call.ll
llvm/test/Transforms/ObjCARC/contract-rv-attr.ll
llvm/test/Transforms/TailCallElim/operand-bundles.ll
################################################################################
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index ab3fba615335..3f930c76fe0a 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -23,7 +23,6 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/CodeGen/CGFunctionInfo.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Analysis/ObjCARCUtil.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
@@ -2079,15 +2078,6 @@ void CodeGenFunction::EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values) {
EmitNounwindRuntimeCall(fn, values);
}
-/// Emit a call to "clang.arc.noop.use", which consumes the result of a call
-/// that has operand bundle "clang.arc.rv".
-void CodeGenFunction::EmitARCNoopIntrinsicUse(ArrayRef<llvm::Value *> values) {
- llvm::Function *&fn = CGM.getObjCEntrypoints().clang_arc_noop_use;
- if (!fn)
- fn = CGM.getIntrinsic(llvm::Intrinsic::objc_clang_arc_noop_use);
- EmitNounwindRuntimeCall(fn, values);
-}
-
static void setARCRuntimeFunctionLinkage(CodeGenModule &CGM, llvm::Value *RTF) {
if (auto *F = dyn_cast<llvm::Function>(RTF)) {
// If the target runtime doesn't naturally support ARC, emit weak
@@ -2314,11 +2304,10 @@ static void emitAutoreleasedReturnValueMarker(CodeGenFunction &CGF) {
// with this marker yet, so leave a breadcrumb for the ARC
// optimizer to pick up.
} else {
- const char *retainRVMarkerKey = llvm::objcarc::getRVMarkerModuleFlagStr();
- if (!CGF.CGM.getModule().getModuleFlag(retainRVMarkerKey)) {
+ const char *markerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
+ if (!CGF.CGM.getModule().getModuleFlag(markerKey)) {
auto *str = llvm::MDString::get(CGF.getLLVMContext(), assembly);
- CGF.CGM.getModule().addModuleFlag(llvm::Module::Error,
- retainRVMarkerKey, str);
+ CGF.CGM.getModule().addModuleFlag(llvm::Module::Error, markerKey, str);
}
}
}
@@ -2328,46 +2317,6 @@ static void emitAutoreleasedReturnValueMarker(CodeGenFunction &CGF) {
CGF.Builder.CreateCall(marker, None, CGF.getBundlesForFunclet(marker));
}
-static llvm::Value *emitOptimizedARCReturnCall(llvm::Value *value,
- bool IsRetainRV,
- CodeGenFunction &CGF) {
- emitAutoreleasedReturnValueMarker(CGF);
-
- // Add operand bundle "clang.arc.rv" to the call instead of emitting retainRV
- // or claimRV calls in the IR. We currently do this only when the optimization
- // level isn't -O0 since global-isel, which is currently run at -O0, doesn't
- // know about the operand bundle.
-
- // FIXME: Do this when the target isn't aarch64.
- if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0 &&
- CGF.CGM.getTarget().getTriple().isAArch64()) {
- llvm::Value *bundleArgs[] = {llvm::ConstantInt::get(
- CGF.Int64Ty, llvm::objcarc::getRVOperandBundleEnum(IsRetainRV))};
- SmallVector<llvm::OperandBundleDef, 1> bundles;
- bundles.emplace_back("clang.arc.rv", bundleArgs);
- auto *oldCall = cast<llvm::CallBase>(value);
- llvm::CallBase *newCall = llvm::CallBase::Create(oldCall, bundles, oldCall);
- newCall->copyMetadata(*oldCall);
- oldCall->replaceAllUsesWith(newCall);
- oldCall->eraseFromParent();
- CGF.EmitARCNoopIntrinsicUse(newCall);
- return newCall;
- }
-
- bool isNoTail =
- CGF.CGM.getTargetCodeGenInfo().markARCOptimizedReturnCallsAsNoTail();
- llvm::CallInst::TailCallKind tailKind =
- isNoTail ? llvm::CallInst::TCK_NoTail : llvm::CallInst::TCK_None;
- ObjCEntrypoints &EPs = CGF.CGM.getObjCEntrypoints();
- llvm::Function *&EP = IsRetainRV
- ? EPs.objc_retainAutoreleasedReturnValue
- : EPs.objc_unsafeClaimAutoreleasedReturnValue;
- llvm::Intrinsic::ID IID =
- IsRetainRV ? llvm::Intrinsic::objc_retainAutoreleasedReturnValue
- : llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue;
- return emitARCValueOperation(CGF, value, nullptr, EP, IID, tailKind);
-}
-
/// Retain the given object which is the result of a function call.
/// call i8* \@objc_retainAutoreleasedReturnValue(i8* %value)
///
@@ -2375,7 +2324,15 @@ static llvm::Value *emitOptimizedARCReturnCall(llvm::Value *value,
/// call with completely
diff erent semantics.
llvm::Value *
CodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) {
- return emitOptimizedARCReturnCall(value, true, *this);
+ emitAutoreleasedReturnValueMarker(*this);
+ llvm::CallInst::TailCallKind tailKind =
+ CGM.getTargetCodeGenInfo().markARCOptimizedReturnCallsAsNoTail()
+ ? llvm::CallInst::TCK_NoTail
+ : llvm::CallInst::TCK_None;
+ return emitARCValueOperation(
+ *this, value, nullptr,
+ CGM.getObjCEntrypoints().objc_retainAutoreleasedReturnValue,
+ llvm::Intrinsic::objc_retainAutoreleasedReturnValue, tailKind);
}
/// Claim a possibly-autoreleased return value at +0. This is only
@@ -2387,7 +2344,15 @@ CodeGenFunction::EmitARCRetainAutoreleasedReturnValue(llvm::Value *value) {
/// call i8* \@objc_unsafeClaimAutoreleasedReturnValue(i8* %value)
llvm::Value *
CodeGenFunction::EmitARCUnsafeClaimAutoreleasedReturnValue(llvm::Value *value) {
- return emitOptimizedARCReturnCall(value, false, *this);
+ emitAutoreleasedReturnValueMarker(*this);
+ llvm::CallInst::TailCallKind tailKind =
+ CGM.getTargetCodeGenInfo().markARCOptimizedReturnCallsAsNoTail()
+ ? llvm::CallInst::TCK_NoTail
+ : llvm::CallInst::TCK_None;
+ return emitARCValueOperation(
+ *this, value, nullptr,
+ CGM.getObjCEntrypoints().objc_unsafeClaimAutoreleasedReturnValue,
+ llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue, tailKind);
}
/// Release the given object.
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index dd77d70c21f4..8eb7adbc8fcb 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -4202,8 +4202,6 @@ class CodeGenFunction : public CodeGenTypeCache {
void EmitARCIntrinsicUse(ArrayRef<llvm::Value*> values);
- void EmitARCNoopIntrinsicUse(ArrayRef<llvm::Value *> values);
-
static Destroyer destroyARCStrongImprecise;
static Destroyer destroyARCStrongPrecise;
static Destroyer destroyARCWeak;
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 4ff7deb70636..618e2f857b07 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -210,9 +210,6 @@ struct ObjCEntrypoints {
/// void clang.arc.use(...);
llvm::Function *clang_arc_use;
-
- /// void clang.arc.noop.use(...);
- llvm::Function *clang_arc_noop_use;
};
/// This class records statistics on instrumentation based profiling.
diff --git a/clang/test/CodeGenObjC/arc-rv-attr.m b/clang/test/CodeGenObjC/arc-rv-attr.m
deleted file mode 100644
index 02314463ccb2..000000000000
--- a/clang/test/CodeGenObjC/arc-rv-attr.m
+++ /dev/null
@@ -1,177 +0,0 @@
-// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK
-
- at class A;
-
-A *makeA(void);
-
-void test_assign() {
- __unsafe_unretained id x;
- x = makeA();
-}
-// CHECK-LABEL: define{{.*}} void @test_assign()
-// CHECK: [[X:%.*]] = alloca i8*
-// CHECK: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.rv"(i64 1) ]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-// CHECK-NEXT: store i8* [[T1]], i8** [[X]]
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: lifetime.end
-// CHECK-NEXT: ret void
-
-void test_assign_assign() {
- __unsafe_unretained id x, y;
- x = y = makeA();
-}
-// CHECK-LABEL: define{{.*}} void @test_assign_assign()
-// CHECK: [[X:%.*]] = alloca i8*
-// CHECK: [[Y:%.*]] = alloca i8*
-// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 1) ]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-// CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
-// CHECK-NEXT: store i8* [[T1]], i8** [[X]]
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: lifetime.end
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: lifetime.end
-// CHECK-NEXT: ret void
-
-void test_strong_assign_assign() {
- __strong id x;
- __unsafe_unretained id y;
- x = y = makeA();
-}
-// CHECK-LABEL: define{{.*}} void @test_strong_assign_assign()
-// CHECK: [[X:%.*]] = alloca i8*
-// CHECK: [[Y:%.*]] = alloca i8*
-// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 0) ]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-// CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
-// CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[X]]
-// CHECK-NEXT: store i8* [[T1]], i8** [[X]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[OLD]]
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: lifetime.end
-// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: lifetime.end
-// CHECK-NEXT: ret void
-
-void test_assign_strong_assign() {
- __unsafe_unretained id x;
- __strong id y;
- x = y = makeA();
-}
-// CHECK-LABEL: define{{.*}} void @test_assign_strong_assign()
-// CHECK: [[X:%.*]] = alloca i8*
-// CHECK: [[Y:%.*]] = alloca i8*
-// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 0) ]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-// CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[Y]]
-// CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[OLD]]
-// CHECK-NEXT: store i8* [[T1]], i8** [[X]]
-// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: lifetime.end
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: lifetime.end
-// CHECK-NEXT: ret void
-
-void test_init() {
- __unsafe_unretained id x = makeA();
-}
-// CHECK-LABEL: define{{.*}} void @test_init()
-// CHECK: [[X:%.*]] = alloca i8*
-// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 1) ]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-// CHECK-NEXT: store i8* [[T1]], i8** [[X]]
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: lifetime.end
-// CHECK-NEXT: ret void
-
-void test_init_assignment() {
- __unsafe_unretained id x;
- __unsafe_unretained id y = x = makeA();
-}
-// CHECK-LABEL: define{{.*}} void @test_init_assignment()
-// CHECK: [[X:%.*]] = alloca i8*
-// CHECK: [[Y:%.*]] = alloca i8*
-// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 1) ]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-// CHECK-NEXT: store i8* [[T1]], i8** [[X]]
-// CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: lifetime.end
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: lifetime.end
-// CHECK-NEXT: ret void
-
-void test_strong_init_assignment() {
- __unsafe_unretained id x;
- __strong id y = x = makeA();
-}
-// CHECK-LABEL: define{{.*}} void @test_strong_init_assignment()
-// CHECK: [[X:%.*]] = alloca i8*
-// CHECK: [[Y:%.*]] = alloca i8*
-// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 0) ]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-// CHECK-NEXT: store i8* [[T1]], i8** [[X]]
-// CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
-// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: lifetime.end
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: lifetime.end
-// CHECK-NEXT: ret void
-
-void test_init_strong_assignment() {
- __strong id x;
- __unsafe_unretained id y = x = makeA();
-}
-// CHECK-LABEL: define{{.*}} void @test_init_strong_assignment()
-// CHECK: [[X:%.*]] = alloca i8*
-// CHECK: [[Y:%.*]] = alloca i8*
-// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 0) ]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8*
-// CHECK-NEXT: [[OLD:%.*]] = load i8*, i8** [[X]]
-// CHECK-NEXT: store i8* [[T1]], i8** [[X]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[OLD]])
-// CHECK-NEXT: store i8* [[T1]], i8** [[Y]]
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: lifetime.end
-// CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[X]]
-// CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]])
-// CHECK-NEXT: bitcast
-// CHECK-NEXT: lifetime.end
-// CHECK-NEXT: ret void
-
-void test_ignored() {
- makeA();
-}
-// CHECK-LABEL: define{{.*}} void @test_ignored()
-// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 1) ]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
-// CHECK-NEXT: ret void
-
-void test_cast_to_void() {
- (void) makeA();
-}
-// CHECK-LABEL: define{{.*}} void @test_cast_to_void()
-// CHECK: [[T0:%.*]] = call [[A]]* @makeA() [ "clang.arc.rv"(i64 1) ]
-// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T0]])
-// CHECK-NEXT: ret void
-
-// This is always at the end of the module.
-
-// CHECK-OPTIMIZED: !llvm.module.flags = !{!0,
-// CHECK-OPTIMIZED: !0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov{{.*}}marker for objc_retainAutoreleaseReturnValue"}
diff --git a/clang/test/CodeGenObjC/arc-unsafeclaim.m b/clang/test/CodeGenObjC/arc-unsafeclaim.m
index 08ff8eca8da5..8f95d1edc96c 100644
--- a/clang/test/CodeGenObjC/arc-unsafeclaim.m
+++ b/clang/test/CodeGenObjC/arc-unsafeclaim.m
@@ -4,10 +4,11 @@
// Make sure it works on x86-32.
// RUN: %clang_cc1 -triple i386-apple-darwin11 -fobjc-runtime=macosx-fragile-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED -check-prefix=CALL
-// Make sure it works on ARM64.
+// Make sure it works on ARM.
// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED -check-prefix=CALL
+// RUN: %clang_cc1 -triple arm64-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED -check-prefix=CALL
-// Make sure it works on ARM.
+// Make sure it works on ARM64.
// RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=CHECK-MARKED -check-prefix=CALL
// RUN: %clang_cc1 -triple armv7-apple-ios9 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-OPTIMIZED -check-prefix=CALL
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index f7974a2c8f40..94951ae2dd3e 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -2325,18 +2325,6 @@ When lowered, any relocated value will be recorded in the corresponding
:ref:`stackmap entry <statepoint-stackmap-format>`. See the intrinsic description
for further details.
-ObjC ARC RetainRV/ClaimRV Operand Bundles
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-A ``"clang.arc.rv"`` operand bundle on a call indicates the call is implicitly
-followed by a marker instruction and a call to an ObjC runtime function that
-uses the result of the call. If the argument passed to the operand bundle is 0,
-``@objc_retainAutoreleasedReturnValue`` is called. If 1 is passed,
-``@objc_unsafeClaimAutoreleasedReturnValue`` is called.
-
-The operand bundle is needed to ensure the call is immediately followed by the
-marker instruction or the ObjC runtime call in the final output.
-
.. _moduleasm:
Module-Level Inline Assembly
diff --git a/llvm/include/llvm/Analysis/ObjCARCUtil.h b/llvm/include/llvm/Analysis/ObjCARCUtil.h
deleted file mode 100644
index a337e6c2751b..000000000000
--- a/llvm/include/llvm/Analysis/ObjCARCUtil.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===- ObjCARCUtil.h - ObjC ARC Utility Functions ---------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file defines ARC utility functions which are used by various parts of
-/// the compiler.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_ANALYSIS_OBJCARCUTIL_H
-#define LLVM_LIB_ANALYSIS_OBJCARCUTIL_H
-
-#include "llvm/IR/InstrTypes.h"
-#include "llvm/IR/LLVMContext.h"
-
-namespace llvm {
-namespace objcarc {
-
-static inline const char *getRVMarkerModuleFlagStr() {
- return "clang.arc.retainAutoreleasedReturnValueMarker";
-}
-
-enum RVOperandBundle : unsigned { RVOB_Retain, RVOB_Claim };
-
-static RVOperandBundle getRVOperandBundleEnum(bool IsRetain) {
- return IsRetain ? RVOB_Retain : RVOB_Claim;
-}
-
-static inline bool hasRVOpBundle(const CallBase *CB, bool IsRetain) {
- auto B = CB->getOperandBundle(LLVMContext::OB_clang_arc_rv);
- if (!B.hasValue())
- return false;
- return cast<ConstantInt>(B->Inputs[0])->getZExtValue() ==
- getRVOperandBundleEnum(IsRetain);
-}
-
-static inline bool hasRVOpBundle(const CallBase *CB) {
- return CB->getOperandBundle(LLVMContext::OB_clang_arc_rv).hasValue();
-}
-
-} // end namespace objcarc
-} // end namespace llvm
-
-#endif
diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h
index c4963f668827..f42ef48de6b3 100644
--- a/llvm/include/llvm/IR/InstrTypes.h
+++ b/llvm/include/llvm/IR/InstrTypes.h
@@ -1214,15 +1214,6 @@ class CallBase : public Instruction {
static CallBase *Create(CallBase *CB, ArrayRef<OperandBundleDef> Bundles,
Instruction *InsertPt = nullptr);
- /// Create a clone of \p CB with operand bundle \p OB added.
- static CallBase *addOperandBundle(CallBase *CB, uint32_t ID,
- OperandBundleDef OB,
- Instruction *InsertPt = nullptr);
-
- /// Create a clone of \p CB with operand bundle \p ID removed.
- static CallBase *removeOperandBundle(CallBase *CB, uint32_t ID,
- Instruction *InsertPt = nullptr);
-
static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Call ||
I->getOpcode() == Instruction::Invoke ||
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 69a5701d5a8d..58f0f86cae63 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -446,9 +446,6 @@ def int_objc_storeWeak : Intrinsic<[llvm_ptr_ty],
llvm_ptr_ty]>;
def int_objc_clang_arc_use : Intrinsic<[],
[llvm_vararg_ty]>;
-def int_objc_clang_arc_noop_use : DefaultAttrsIntrinsic<[],
- [llvm_vararg_ty],
- [IntrInaccessibleMemOnly]>;
def int_objc_unsafeClaimAutoreleasedReturnValue : Intrinsic<[llvm_ptr_ty],
[llvm_ptr_ty]>;
def int_objc_retainedObject : Intrinsic<[llvm_ptr_ty],
diff --git a/llvm/include/llvm/IR/LLVMContext.h b/llvm/include/llvm/IR/LLVMContext.h
index 23a01b8e0471..8f8a35d07c64 100644
--- a/llvm/include/llvm/IR/LLVMContext.h
+++ b/llvm/include/llvm/IR/LLVMContext.h
@@ -93,7 +93,6 @@ class LLVMContext {
OB_cfguardtarget = 3, // "cfguardtarget"
OB_preallocated = 4, // "preallocated"
OB_gc_live = 5, // "gc-live"
- OB_clang_arc_rv = 6, // "clang.arc.rv"
};
/// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
diff --git a/llvm/lib/Analysis/ObjCARCInstKind.cpp b/llvm/lib/Analysis/ObjCARCInstKind.cpp
index 704d15f3280d..951907804227 100644
--- a/llvm/lib/Analysis/ObjCARCInstKind.cpp
+++ b/llvm/lib/Analysis/ObjCARCInstKind.cpp
@@ -140,7 +140,6 @@ ARCInstKind llvm::objcarc::GetFunctionClass(const Function *F) {
return ARCInstKind::User;
case Intrinsic::objc_sync_exit:
return ARCInstKind::User;
- case Intrinsic::objc_clang_arc_noop_use:
case Intrinsic::objc_arc_annotation_topdown_bbstart:
case Intrinsic::objc_arc_annotation_topdown_bbend:
case Intrinsic::objc_arc_annotation_bottomup_bbstart:
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 936b56dad485..5c94a83f719c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -2782,10 +2782,11 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) {
// Deopt bundles are lowered in LowerCallSiteWithDeoptBundle, and we don't
// have to do anything here to lower funclet bundles.
- assert(!I.hasOperandBundlesOtherThan(
- {LLVMContext::OB_deopt, LLVMContext::OB_gc_transition,
- LLVMContext::OB_gc_live, LLVMContext::OB_funclet,
- LLVMContext::OB_cfguardtarget, LLVMContext::OB_clang_arc_rv}) &&
+ assert(!I.hasOperandBundlesOtherThan({LLVMContext::OB_deopt,
+ LLVMContext::OB_gc_transition,
+ LLVMContext::OB_gc_live,
+ LLVMContext::OB_funclet,
+ LLVMContext::OB_cfguardtarget}) &&
"Cannot lower invokes with arbitrary operand bundles yet!");
const Value *Callee(I.getCalledOperand());
@@ -7872,8 +7873,7 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
// CFGuardTarget bundles are lowered in LowerCallTo.
assert(!I.hasOperandBundlesOtherThan(
{LLVMContext::OB_deopt, LLVMContext::OB_funclet,
- LLVMContext::OB_cfguardtarget, LLVMContext::OB_preallocated,
- LLVMContext::OB_clang_arc_rv}) &&
+ LLVMContext::OB_cfguardtarget, LLVMContext::OB_preallocated}) &&
"Cannot lower calls with arbitrary operand bundles!");
SDValue Callee = getValue(I.getCalledOperand());
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index b73528d89752..d6b4a4f5030f 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -424,35 +424,6 @@ CallBase::BundleOpInfo &CallBase::getBundleOpInfoForOperand(unsigned OpIdx) {
return *Current;
}
-CallBase *CallBase::addOperandBundle(CallBase *CB, uint32_t ID,
- OperandBundleDef OB,
- Instruction *InsertPt) {
- if (CB->getOperandBundle(ID))
- return CB;
-
- SmallVector<OperandBundleDef, 1> Bundles;
- CB->getOperandBundlesAsDefs(Bundles);
- Bundles.push_back(OB);
- return Create(CB, Bundles, InsertPt);
-}
-
-CallBase *CallBase::removeOperandBundle(CallBase *CB, uint32_t ID,
- Instruction *InsertPt) {
- SmallVector<OperandBundleDef, 1> Bundles;
- bool CreateNew = false;
-
- for (unsigned I = 0, E = CB->getNumOperandBundles(); I != E; ++I) {
- auto Bundle = CB->getOperandBundleAt(I);
- if (Bundle.getTagID() == ID) {
- CreateNew = true;
- continue;
- }
- Bundles.emplace_back(Bundle);
- }
-
- return CreateNew ? Create(CB, Bundles, InsertPt) : CB;
-}
-
//===----------------------------------------------------------------------===//
// CallInst Implementation
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp
index 9f9a30de23e3..4f292101256d 100644
--- a/llvm/lib/IR/LLVMContext.cpp
+++ b/llvm/lib/IR/LLVMContext.cpp
@@ -78,11 +78,6 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
"gc-transition operand bundle id drifted!");
(void)GCLiveEntry;
- auto *ClangARCRVEntry = pImpl->getOrInsertBundleTag("clang.arc.rv");
- assert(ClangARCRVEntry->second == LLVMContext::OB_clang_arc_rv &&
- "clang.arc.rv operand bundle id drifted!");
- (void)ClangARCRVEntry;
-
SyncScope::ID SingleThreadSSID =
pImpl->getOrInsertSyncScopeID("singlethread");
assert(SingleThreadSSID == SyncScope::SingleThread &&
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 55b6cf177d0a..c87478afe65c 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -29,7 +29,6 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/Analysis/ObjCARCUtil.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
@@ -5654,11 +5653,11 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
}
unsigned CallOpc = AArch64ISD::CALL;
- // Calls with operand bundle "clang.arc.rv" are special. They should be
- // expanded to the call, directly followed by a special marker sequence. Use
- // the CALL_RVMARKER to do that.
- if (CLI.CB && objcarc::hasRVOpBundle(CLI.CB)) {
- assert(!IsTailCall && "tail calls cannot be marked with clang.arc.rv");
+ // Calls marked with "rv_marker" are special. They should be expanded to the
+ // call, directly followed by a special marker sequence. Use the CALL_RVMARKER
+ // to do that.
+ if (CLI.CB && CLI.CB->hasRetAttr("rv_marker")) {
+ assert(!IsTailCall && "tail calls cannot be marked with rv_marker");
CallOpc = AArch64ISD::CALL_RVMARKER;
}
diff --git a/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h b/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h
index 764dc5f92707..258dc9240815 100644
--- a/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h
+++ b/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h
@@ -42,7 +42,6 @@ enum class ARCRuntimeEntryPointKind {
Autorelease,
StoreStrong,
RetainRV,
- ClaimRV,
RetainAutorelease,
RetainAutoreleaseRV,
};
@@ -62,7 +61,6 @@ class ARCRuntimeEntryPoints {
Autorelease = nullptr;
StoreStrong = nullptr;
RetainRV = nullptr;
- ClaimRV = nullptr;
RetainAutorelease = nullptr;
RetainAutoreleaseRV = nullptr;
}
@@ -87,9 +85,6 @@ class ARCRuntimeEntryPoints {
case ARCRuntimeEntryPointKind::RetainRV:
return getIntrinsicEntryPoint(RetainRV,
Intrinsic::objc_retainAutoreleasedReturnValue);
- case ARCRuntimeEntryPointKind::ClaimRV:
- return getIntrinsicEntryPoint(
- ClaimRV, Intrinsic::objc_unsafeClaimAutoreleasedReturnValue);
case ARCRuntimeEntryPointKind::RetainAutorelease:
return getIntrinsicEntryPoint(RetainAutorelease,
Intrinsic::objc_retainAutorelease);
@@ -126,9 +121,6 @@ class ARCRuntimeEntryPoints {
/// Declaration for objc_retainAutoreleasedReturnValue().
Function *RetainRV = nullptr;
- /// Declaration for objc_unsafeClaimAutoreleasedReturnValue().
- Function *ClaimRV = nullptr;
-
/// Declaration for objc_retainAutorelease().
Function *RetainAutorelease = nullptr;
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp
index c4b6d60cad36..970136392fdd 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp
@@ -14,12 +14,7 @@
#include "ObjCARC.h"
#include "llvm-c/Initialization.h"
-#include "llvm/Analysis/ObjCARCUtil.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/InlineAsm.h"
-#include "llvm/IR/Instructions.h"
#include "llvm/InitializePasses.h"
-#include "llvm/Transforms/Utils/BasicBlockUtils.h"
namespace llvm {
class PassRegistry;
@@ -42,91 +37,3 @@ void llvm::initializeObjCARCOpts(PassRegistry &Registry) {
void LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R) {
initializeObjCARCOpts(*unwrap(R));
}
-
-CallInst *objcarc::createCallInstWithColors(
- FunctionCallee Func, ArrayRef<Value *> Args, const Twine &NameStr,
- Instruction *InsertBefore,
- const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
- FunctionType *FTy = Func.getFunctionType();
- Value *Callee = Func.getCallee();
- SmallVector<OperandBundleDef, 1> OpBundles;
-
- if (!BlockColors.empty()) {
- const ColorVector &CV = BlockColors.find(InsertBefore->getParent())->second;
- assert(CV.size() == 1 && "non-unique color for block!");
- Instruction *EHPad = CV.front()->getFirstNonPHI();
- if (EHPad->isEHPad())
- OpBundles.emplace_back("funclet", EHPad);
- }
-
- return CallInst::Create(FTy, Callee, Args, OpBundles, NameStr, InsertBefore);
-}
-
-std::pair<bool, bool>
-BundledRetainClaimRVs::insertAfterInvokes(Function &F, DominatorTree *DT) {
- bool Changed = false, CFGChanged = false;
-
- for (BasicBlock &BB : F) {
- auto *I = dyn_cast<InvokeInst>(BB.getTerminator());
-
- if (!I)
- continue;
-
- if (!objcarc::hasRVOpBundle(I))
- continue;
-
- BasicBlock *DestBB = I->getNormalDest();
-
- if (!DestBB->getSinglePredecessor()) {
- assert(I->getSuccessor(0) == DestBB &&
- "the normal dest is expected to be the first successor");
- DestBB = SplitCriticalEdge(I, 0, CriticalEdgeSplittingOptions(DT));
- CFGChanged = true;
- }
-
- // We don't have to call insertRVCallWithColors since DestBB is the normal
- // destination of the invoke.
- insertRVCall(&*DestBB->getFirstInsertionPt(), I);
- Changed = true;
- }
-
- return std::make_pair(Changed, CFGChanged);
-}
-
-CallInst *BundledRetainClaimRVs::insertRVCall(Instruction *InsertPt,
- CallBase *AnnotatedCall) {
- DenseMap<BasicBlock *, ColorVector> BlockColors;
- return insertRVCallWithColors(InsertPt, AnnotatedCall, BlockColors);
-}
-
-CallInst *BundledRetainClaimRVs::insertRVCallWithColors(
- Instruction *InsertPt, CallBase *AnnotatedCall,
- const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
- IRBuilder<> Builder(InsertPt);
- bool IsRetainRV = objcarc::hasRVOpBundle(AnnotatedCall, true);
- Function *Func = EP.get(IsRetainRV ? ARCRuntimeEntryPointKind::RetainRV
- : ARCRuntimeEntryPointKind::ClaimRV);
- Type *ParamTy = Func->getArg(0)->getType();
- Value *CallArg = Builder.CreateBitCast(AnnotatedCall, ParamTy);
- auto *Call =
- createCallInstWithColors(Func, CallArg, "", InsertPt, BlockColors);
- RVCalls[Call] = AnnotatedCall;
- return Call;
-}
-
-BundledRetainClaimRVs::~BundledRetainClaimRVs() {
- if (ContractPass) {
- // At this point, we know that the annotated calls can't be tail calls as
- // they are followed by marker instructions and retainRV/claimRV calls. Mark
- // them as notail, so that the backend knows these calls can't be tail
- // calls.
- for (auto P : RVCalls)
- if (auto *CI = dyn_cast<CallInst>(P.second))
- CI->setTailCallKind(CallInst::TCK_NoTail);
- } else {
- for (auto P : RVCalls)
- EraseInstruction(P.first);
- }
-
- RVCalls.clear();
-}
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARC.h b/llvm/lib/Transforms/ObjCARC/ObjCARC.h
index d4d88569694d..8227a8c6f75f 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARC.h
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARC.h
@@ -22,10 +22,7 @@
#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H
#define LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H
-#include "ARCRuntimeEntryPoints.h"
-#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
-#include "llvm/Analysis/ObjCARCUtil.h"
#include "llvm/Transforms/Utils/Local.h"
namespace llvm {
@@ -90,67 +87,6 @@ void getEquivalentPHIs(PHINodeTy &PN, VectorTy &PHIList) {
}
}
-static inline MDString *getRVInstMarker(Module &M) {
- const char *MarkerKey = getRVMarkerModuleFlagStr();
- return dyn_cast_or_null<MDString>(M.getModuleFlag(MarkerKey));
-}
-
-/// Create a call instruction with the correct funclet token. This should be
-/// called instead of calling CallInst::Create directly unless the call is
-/// going to be removed from the IR before WinEHPrepare.
-CallInst *createCallInstWithColors(
- FunctionCallee Func, ArrayRef<Value *> Args, const Twine &NameStr,
- Instruction *InsertBefore,
- const DenseMap<BasicBlock *, ColorVector> &BlockColors);
-
-class BundledRetainClaimRVs {
-public:
- BundledRetainClaimRVs(ARCRuntimeEntryPoints &P, bool ContractPass)
- : EP(P), ContractPass(ContractPass) {}
- ~BundledRetainClaimRVs();
-
- /// Insert a retainRV/claimRV call to the normal destination blocks of invokes
- /// with operand bundle "clang.arc.rv". If the edge to the normal destination
- /// block is a critical edge, split it.
- std::pair<bool, bool> insertAfterInvokes(Function &F, DominatorTree *DT);
-
- /// Insert a retainRV/claimRV call.
- CallInst *insertRVCall(Instruction *InsertPt, CallBase *AnnotatedCall);
-
- /// Insert a retainRV/claimRV call with colors.
- CallInst *insertRVCallWithColors(
- Instruction *InsertPt, CallBase *AnnotatedCall,
- const DenseMap<BasicBlock *, ColorVector> &BlockColors);
-
- /// See if an instruction is a bundled retainRV/claimRV call.
- bool contains(const Instruction *I) const {
- if (auto *CI = dyn_cast<CallInst>(I))
- return RVCalls.count(CI);
- return false;
- }
-
- /// Remove a retainRV/claimRV call entirely.
- void eraseInst(CallInst *CI) {
- auto It = RVCalls.find(CI);
- if (It != RVCalls.end()) {
- auto *NewCall = CallBase::removeOperandBundle(
- It->second, LLVMContext::OB_clang_arc_rv, It->second);
- NewCall->copyMetadata(*It->second);
- It->second->replaceAllUsesWith(NewCall);
- It->second->eraseFromParent();
- RVCalls.erase(It);
- }
- EraseInstruction(CI);
- }
-
-private:
- /// A map of inserted retainRV/claimRV calls to annotated calls/invokes.
- DenseMap<CallInst *, CallBase *> RVCalls;
-
- ARCRuntimeEntryPoints &EP;
- bool ContractPass;
-};
-
} // end namespace objcarc
} // end namespace llvm
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
index 5146e41aa617..86d161116e8c 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
@@ -32,7 +32,6 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/EHPersonalities.h"
-#include "llvm/Analysis/ObjCARCUtil.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/InstIterator.h"
@@ -64,12 +63,13 @@ namespace {
class ObjCARCContract {
bool Changed;
- bool CFGChanged;
AAResults *AA;
DominatorTree *DT;
ProvenanceAnalysis PA;
ARCRuntimeEntryPoints EP;
- BundledRetainClaimRVs *BundledInsts = nullptr;
+
+ /// A flag indicating whether this optimization pass should run.
+ bool Run;
/// The inline asm string to insert between calls and RetainRV calls to make
/// the optimization work on targets which need it.
@@ -98,7 +98,6 @@ class ObjCARCContract {
public:
bool init(Module &M);
bool run(Function &F, AAResults *AA, DominatorTree *DT);
- bool hasCFGChanged() const { return CFGChanged; }
};
class ObjCARCContractLegacyPass : public FunctionPass {
@@ -305,6 +304,32 @@ findRetainForStoreStrongContraction(Value *New, StoreInst *Store,
return Retain;
}
+/// Create a call instruction with the correct funclet token. Should be used
+/// instead of calling CallInst::Create directly.
+static CallInst *
+createCallInst(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
+ const Twine &NameStr, Instruction *InsertBefore,
+ const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
+ SmallVector<OperandBundleDef, 1> OpBundles;
+ if (!BlockColors.empty()) {
+ const ColorVector &CV = BlockColors.find(InsertBefore->getParent())->second;
+ assert(CV.size() == 1 && "non-unique color for block!");
+ Instruction *EHPad = CV.front()->getFirstNonPHI();
+ if (EHPad->isEHPad())
+ OpBundles.emplace_back("funclet", EHPad);
+ }
+
+ return CallInst::Create(FTy, Func, Args, OpBundles, NameStr, InsertBefore);
+}
+
+static CallInst *
+createCallInst(FunctionCallee Func, ArrayRef<Value *> Args, const Twine &NameStr,
+ Instruction *InsertBefore,
+ const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
+ return createCallInst(Func.getFunctionType(), Func.getCallee(), Args, NameStr,
+ InsertBefore, BlockColors);
+}
+
/// Attempt to merge an objc_release with a store, load, and objc_retain to form
/// an objc_storeStrong. An objc_storeStrong:
///
@@ -386,8 +411,7 @@ void ObjCARCContract::tryToContractReleaseIntoStoreStrong(
if (Args[1]->getType() != I8X)
Args[1] = new BitCastInst(Args[1], I8X, "", Store);
Function *Decl = EP.get(ARCRuntimeEntryPointKind::StoreStrong);
- CallInst *StoreStrong =
- objcarc::createCallInstWithColors(Decl, Args, "", Store, BlockColors);
+ CallInst *StoreStrong = createCallInst(Decl, Args, "", Store, BlockColors);
StoreStrong->setDoesNotThrow();
StoreStrong->setDebugLoc(Store->getDebugLoc());
@@ -432,14 +456,9 @@ bool ObjCARCContract::tryToPeepholeInstruction(
case ARCInstKind::RetainRV:
case ARCInstKind::ClaimRV: {
// If we're compiling for a target which needs a special inline-asm
- // marker to do the return value optimization and the retainRV/claimRV call
- // wasn't bundled with a call, insert the marker now.
+ // marker to do the return value optimization, insert it now.
if (!RVInstMarker)
return false;
-
- if (BundledInsts->contains(Inst))
- return false;
-
BasicBlock::iterator BBI = Inst->getIterator();
BasicBlock *InstParent = Inst->getParent();
@@ -467,7 +486,7 @@ bool ObjCARCContract::tryToPeepholeInstruction(
RVInstMarker->getString(),
/*Constraints=*/"", /*hasSideEffects=*/true);
- objcarc::createCallInstWithColors(IA, None, "", Inst, BlockColors);
+ createCallInst(IA, None, "", Inst, BlockColors);
}
decline_rv_optimization:
return false;
@@ -506,12 +525,6 @@ bool ObjCARCContract::tryToPeepholeInstruction(
Inst->eraseFromParent();
return true;
default:
- if (auto *CI = dyn_cast<CallInst>(Inst))
- if (CI->getIntrinsicID() == Intrinsic::objc_clang_arc_noop_use) {
- // Remove calls to @llvm.objc.clang.arc.noop.use(...).
- Changed = true;
- CI->eraseFromParent();
- }
return true;
}
}
@@ -521,10 +534,16 @@ bool ObjCARCContract::tryToPeepholeInstruction(
//===----------------------------------------------------------------------===//
bool ObjCARCContract::init(Module &M) {
+ // If nothing in the Module uses ARC, don't do anything.
+ Run = ModuleHasARC(M);
+ if (!Run)
+ return false;
+
EP.init(&M);
// Initialize RVInstMarker.
- RVInstMarker = getRVInstMarker(M);
+ const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
+ RVInstMarker = dyn_cast_or_null<MDString>(M.getModuleFlag(MarkerKey));
return false;
}
@@ -533,16 +552,14 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
if (!EnableARCOpts)
return false;
- Changed = CFGChanged = false;
+ // If nothing in the Module uses ARC, don't do anything.
+ if (!Run)
+ return false;
+
+ Changed = false;
AA = A;
DT = D;
PA.setAA(A);
- BundledRetainClaimRVs BRV(EP, true);
- BundledInsts = &BRV;
-
- std::pair<bool, bool> R = BundledInsts->insertAfterInvokes(F, DT);
- Changed |= R.first;
- CFGChanged |= R.second;
DenseMap<BasicBlock *, ColorVector> BlockColors;
if (F.hasPersonalityFn() &&
@@ -567,13 +584,6 @@ bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
LLVM_DEBUG(dbgs() << "Visiting: " << *Inst << "\n");
- if (auto *CI = dyn_cast<CallInst>(Inst))
- if (objcarc::hasRVOpBundle(CI)) {
- BundledInsts->insertRVCallWithColors(&*I, CI, BlockColors);
- --I;
- Changed = true;
- }
-
// First try to peephole Inst. If there is nothing further we can do in
// terms of undoing objc-arc-expand, process the next inst.
if (tryToPeepholeInstruction(F, Inst, I, TailOkForStoreStrongs,
@@ -723,6 +733,7 @@ INITIALIZE_PASS_END(ObjCARCContractLegacyPass, "objc-arc-contract",
void ObjCARCContractLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<DominatorTreeWrapperPass>();
+ AU.setPreservesCFG();
}
Pass *llvm::createObjCARCContractPass() {
@@ -746,11 +757,9 @@ PreservedAnalyses ObjCARCContractPass::run(Function &F,
bool Changed = OCAC.run(F, &AM.getResult<AAManager>(F),
&AM.getResult<DominatorTreeAnalysis>(F));
- bool CFGChanged = OCAC.hasCFGChanged();
if (Changed) {
PreservedAnalyses PA;
- if (!CFGChanged)
- PA.preserveSet<CFGAnalyses>();
+ PA.preserveSet<CFGAnalyses>();
return PA;
}
return PreservedAnalyses::all();
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
index d97d58f518e3..1c447499519c 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
@@ -41,7 +41,6 @@
#include "llvm/Analysis/ObjCARCAliasAnalysis.h"
#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
#include "llvm/Analysis/ObjCARCInstKind.h"
-#include "llvm/Analysis/ObjCARCUtil.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constant.h"
@@ -484,7 +483,6 @@ namespace {
/// The main ARC optimization pass.
class ObjCARCOpt {
bool Changed;
- bool CFGChanged;
ProvenanceAnalysis PA;
/// A cache of references to runtime entry point constants.
@@ -494,7 +492,8 @@ class ObjCARCOpt {
/// MDKind identifiers.
ARCMDKindCache MDKindCache;
- BundledRetainClaimRVs *BundledInsts = nullptr;
+ /// A flag indicating whether this optimization pass should run.
+ bool Run;
/// A flag indicating whether the optimization that removes or moves
/// retain/release pairs should be performed.
@@ -574,7 +573,6 @@ class ObjCARCOpt {
void init(Module &M);
bool run(Function &F, AAResults &AA);
void releaseMemory();
- bool hasCFGChanged() const { return CFGChanged; }
};
/// The main ARC optimization pass.
@@ -612,6 +610,8 @@ Pass *llvm::createObjCARCOptPass() { return new ObjCARCOptLegacyPass(); }
void ObjCARCOptLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<ObjCARCAAWrapperPass>();
AU.addRequired<AAResultsWrapperPass>();
+ // ARC optimization doesn't currently split critical edges.
+ AU.setPreservesCFG();
}
/// Turn objc_retainAutoreleasedReturnValue into objc_retain if the operand is
@@ -640,9 +640,6 @@ ObjCARCOpt::OptimizeRetainRVCall(Function &F, Instruction *RetainRV) {
}
}
- assert(!BundledInsts->contains(RetainRV) &&
- "a bundled retainRV's argument should be a call");
-
// Turn it to a plain objc_retain.
Changed = true;
++NumPeeps;
@@ -664,9 +661,6 @@ bool ObjCARCOpt::OptimizeInlinedAutoreleaseRVCall(
Function &F, DenseMap<BasicBlock *, ColorVector> &BlockColors,
Instruction *Inst, const Value *&Arg, ARCInstKind Class,
Instruction *AutoreleaseRV, const Value *&AutoreleaseRVArg) {
- if (BundledInsts->contains(Inst))
- return false;
-
// Must be in the same basic block.
assert(Inst->getParent() == AutoreleaseRV->getParent());
@@ -850,12 +844,6 @@ void ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) {
Instruction *Inst = &*I++;
- if (auto *CI = dyn_cast<CallInst>(Inst))
- if (objcarc::hasRVOpBundle(CI)) {
- BundledInsts->insertRVCall(&*I, CI);
- Changed = true;
- }
-
ARCInstKind Class = GetBasicARCInstKind(Inst);
// Skip this loop if this instruction isn't itself an ARC intrinsic.
@@ -934,11 +922,6 @@ void ObjCARCOpt::OptimizeIndividualCallImpl(
// We can delete this call if it takes an inert value.
SmallPtrSet<Value *, 1> VisitedPhis;
- if (BundledInsts->contains(Inst)) {
- UsedInThisFunction |= 1 << unsigned(Class);
- return;
- }
-
if (IsNoopOnGlobal(Class))
if (isInertARCValue(Inst->getOperand(0), VisitedPhis)) {
if (!Inst->getType()->isVoidTy())
@@ -1559,7 +1542,7 @@ ObjCARCOpt::VisitInstructionTopDown(Instruction *Inst,
if (Ptr == Arg)
continue; // Handled above.
TopDownPtrState &S = MI->second;
- if (S.HandlePotentialAlterRefCount(Inst, Ptr, PA, Class, *BundledInsts))
+ if (S.HandlePotentialAlterRefCount(Inst, Ptr, PA, Class))
continue;
S.HandlePotentialUse(Inst, Ptr, PA, Class);
@@ -2360,7 +2343,7 @@ void ObjCARCOpt::OptimizeReturns(Function &F) {
++NumRets;
LLVM_DEBUG(dbgs() << "Erasing: " << *Retain << "\nErasing: " << *Autorelease
<< "\n");
- BundledInsts->eraseInst(Retain);
+ EraseInstruction(Retain);
EraseInstruction(Autorelease);
}
}
@@ -2393,6 +2376,11 @@ void ObjCARCOpt::init(Module &M) {
if (!EnableARCOpts)
return;
+ // If nothing in the Module uses ARC, don't do anything.
+ Run = ModuleHasARC(M);
+ if (!Run)
+ return;
+
// Intuitively, objc_retain and others are nocapture, however in practice
// they are not, because they return their argument value. And objc_release
// calls finalizers which can have arbitrary side effects.
@@ -2406,18 +2394,16 @@ bool ObjCARCOpt::run(Function &F, AAResults &AA) {
if (!EnableARCOpts)
return false;
- Changed = CFGChanged = false;
- BundledRetainClaimRVs BRV(EP, false);
- BundledInsts = &BRV;
+ // If nothing in the Module uses ARC, don't do anything.
+ if (!Run)
+ return false;
+
+ Changed = false;
LLVM_DEBUG(dbgs() << "<<< ObjCARCOpt: Visiting Function: " << F.getName()
<< " >>>"
"\n");
- std::pair<bool, bool> R = BundledInsts->insertAfterInvokes(F, nullptr);
- Changed |= R.first;
- CFGChanged |= R.second;
-
PA.setAA(&AA);
#ifndef NDEBUG
@@ -2482,11 +2468,9 @@ PreservedAnalyses ObjCARCOptPass::run(Function &F,
OCAO.init(*F.getParent());
bool Changed = OCAO.run(F, AM.getResult<AAManager>(F));
- bool CFGChanged = OCAO.hasCFGChanged();
if (Changed) {
PreservedAnalyses PA;
- if (!CFGChanged)
- PA.preserveSet<CFGAnalyses>();
+ PA.preserveSet<CFGAnalyses>();
return PA;
}
return PreservedAnalyses::all();
diff --git a/llvm/lib/Transforms/ObjCARC/PtrState.cpp b/llvm/lib/Transforms/ObjCARC/PtrState.cpp
index cf4d029d37ac..6071ec3e4d91 100644
--- a/llvm/lib/Transforms/ObjCARC/PtrState.cpp
+++ b/llvm/lib/Transforms/ObjCARC/PtrState.cpp
@@ -11,7 +11,6 @@
#include "ObjCARC.h"
#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
#include "llvm/Analysis/ObjCARCInstKind.h"
-#include "llvm/Analysis/ObjCARCUtil.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
@@ -281,12 +280,6 @@ void BottomUpPtrState::HandlePotentialUse(BasicBlock *BB, Instruction *Inst,
InsertAfter = skipDebugIntrinsics(InsertAfter);
InsertReverseInsertPt(&*InsertAfter);
-
- // Don't insert anything between a call/invoke with operand bundle
- // "clang.arc.rv" and the retainRV/claimRV call that uses the call result.
- if (auto *CB = dyn_cast<CallBase>(Inst))
- if (objcarc::hasRVOpBundle(CB))
- SetCFGHazardAfflicted(true);
};
// Check for possible direct uses.
@@ -384,9 +377,10 @@ bool TopDownPtrState::MatchWithRelease(ARCMDKindCache &Cache,
llvm_unreachable("Sequence unknown enum value");
}
-bool TopDownPtrState::HandlePotentialAlterRefCount(
- Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA,
- ARCInstKind Class, const BundledRetainClaimRVs &BundledRVs) {
+bool TopDownPtrState::HandlePotentialAlterRefCount(Instruction *Inst,
+ const Value *Ptr,
+ ProvenanceAnalysis &PA,
+ ARCInstKind Class) {
// Check for possible releases. Treat clang.arc.use as a releasing instruction
// to prevent sinking a retain past it.
if (!CanDecrementRefCount(Inst, Ptr, PA, Class) &&
@@ -402,11 +396,6 @@ bool TopDownPtrState::HandlePotentialAlterRefCount(
assert(!HasReverseInsertPts());
InsertReverseInsertPt(Inst);
- // Don't insert anything between a call/invoke with operand bundle
- // "clang.arc.rv" and the retainRV/claimRV call that uses the call result.
- if (BundledRVs.contains(Inst))
- SetCFGHazardAfflicted(true);
-
// One call can't cause a transition from S_Retain to S_CanRelease
// and S_CanRelease to S_Use. If we've made the first transition,
// we're done.
diff --git a/llvm/lib/Transforms/ObjCARC/PtrState.h b/llvm/lib/Transforms/ObjCARC/PtrState.h
index f143120ad6a4..66614c06cb79 100644
--- a/llvm/lib/Transforms/ObjCARC/PtrState.h
+++ b/llvm/lib/Transforms/ObjCARC/PtrState.h
@@ -31,7 +31,6 @@ class Value;
namespace objcarc {
class ARCMDKindCache;
-class BundledRetainClaimRVs;
class ProvenanceAnalysis;
/// \enum Sequence
@@ -203,8 +202,7 @@ struct TopDownPtrState : PtrState {
ProvenanceAnalysis &PA, ARCInstKind Class);
bool HandlePotentialAlterRefCount(Instruction *Inst, const Value *Ptr,
- ProvenanceAnalysis &PA, ARCInstKind Class,
- const BundledRetainClaimRVs &BundledRVs);
+ ProvenanceAnalysis &PA, ARCInstKind Class);
};
} // end namespace objcarc
diff --git a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp
index a2b80806f662..9e7cccc88412 100644
--- a/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/TailRecursionElimination.cpp
@@ -247,9 +247,7 @@ static bool markTails(Function &F, bool &AllCallsAreTailCalls,
isa<PseudoProbeInst>(&I))
continue;
- // Special-case operand bundle "clang.arc.rv".
- bool IsNoTail = CI->isNoTailCall() || CI->hasOperandBundlesOtherThan(
- LLVMContext::OB_clang_arc_rv);
+ bool IsNoTail = CI->isNoTailCall() || CI->hasOperandBundles();
if (!IsNoTail && CI->doesNotAccessMemory()) {
// A call to a readnone function whose arguments are all things computed
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 434b11fb613d..3026342cc4a6 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -27,9 +27,8 @@
#include "llvm/Analysis/CaptureTracking.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/InstructionSimplify.h"
-#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
-#include "llvm/Analysis/ObjCARCUtil.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
+#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/IR/Argument.h"
@@ -62,7 +61,6 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Transforms/Utils/AssumeBundleBuilder.h"
#include "llvm/Transforms/Utils/Cloning.h"
-#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <algorithm>
#include <cassert>
@@ -1652,98 +1650,6 @@ void llvm::updateProfileCallee(
}
}
-/// An operand bundle "clang.arc.rv" on a call indicates the call result is
-/// implicitly consumed by a call to retainRV or claimRV immediately after the
-/// call. This function inlines the retainRV/claimRV calls.
-///
-/// There are three cases to consider:
-///
-/// 1. If there is a call to autoreleaseRV that takes a pointer to the returned
-/// object in the callee return block, the autoreleaseRV call and the
-/// retainRV/claimRV call in the caller cancel out. If the call in the caller
-/// is a claimRV call, a call to objc_release is emitted.
-///
-/// 2. If there is a call in the callee return block that doesn't have operand
-/// bundle "clang.arc.rv", the operand bundle on the original call is
-/// transferred to the call in the callee.
-///
-/// 3. Otherwise, a call to objc_retain is inserted if the call in the caller is
-/// a retainRV call.
-static void
-inlineRetainOrClaimRVCalls(CallBase &CB,
- const SmallVectorImpl<ReturnInst *> &Returns) {
- Module *Mod = CB.getModule();
- bool IsRetainRV = objcarc::hasRVOpBundle(&CB, true), IsClaimRV = !IsRetainRV;
-
- for (auto *RI : Returns) {
- Value *RetOpnd = objcarc::GetRCIdentityRoot(RI->getOperand(0));
- BasicBlock::reverse_iterator I = ++(RI->getIterator().getReverse());
- BasicBlock::reverse_iterator EI = RI->getParent()->rend();
- bool InsertRetainCall = IsRetainRV;
- IRBuilder<> Builder(RI->getContext());
-
- // Walk backwards through the basic block looking for either a matching
- // autoreleaseRV call or an unannotated call.
- for (; I != EI;) {
- auto CurI = I++;
-
- // Ignore casts.
- if (isa<CastInst>(*CurI))
- continue;
-
- if (auto *II = dyn_cast<IntrinsicInst>(&*CurI)) {
- if (II->getIntrinsicID() == Intrinsic::objc_autoreleaseReturnValue &&
- II->hasNUses(0) &&
- objcarc::GetRCIdentityRoot(II->getOperand(0)) == RetOpnd) {
- // If we've found a matching authoreleaseRV call:
- // - If the call is annotated with claimRV, insert a call to
- // objc_release and erase the autoreleaseRV call.
- // - If the call is annotated with retainRV, just erase the
- // autoreleaseRV call.
- if (IsClaimRV) {
- Builder.SetInsertPoint(II);
- Function *IFn =
- Intrinsic::getDeclaration(Mod, Intrinsic::objc_release);
- Value *BC =
- Builder.CreateBitCast(RetOpnd, IFn->getArg(0)->getType());
- Builder.CreateCall(IFn, BC, "");
- }
- II->eraseFromParent();
- InsertRetainCall = false;
- }
- } else if (auto *CI = dyn_cast<CallInst>(&*CurI)) {
- if (objcarc::GetRCIdentityRoot(CI) == RetOpnd &&
- !objcarc::hasRVOpBundle(CI)) {
- // If we've found an unannotated call that defines RetOpnd, add a
- // "clang.arc.rv" operand bundle.
- Value *BundleArgs[] = {
- ConstantInt::get(Builder.getInt64Ty(),
- objcarc::getRVOperandBundleEnum(IsRetainRV))};
- OperandBundleDef OB("clang.arc.rv", BundleArgs);
- auto *NewCall = CallBase::addOperandBundle(
- CI, LLVMContext::OB_clang_arc_rv, OB, CI);
- NewCall->copyMetadata(*CI);
- CI->replaceAllUsesWith(NewCall);
- CI->eraseFromParent();
- InsertRetainCall = false;
- }
- }
-
- break;
- }
-
- if (InsertRetainCall) {
- // The call has operand bundle "clang.arc.rv"="retain" and we've failed to
- // find a matching autoreleaseRV or an annotated call in the callee. Emit
- // a call to objc_retain.
- Builder.SetInsertPoint(RI);
- Function *IFn = Intrinsic::getDeclaration(Mod, Intrinsic::objc_retain);
- Value *BC = Builder.CreateBitCast(RetOpnd, IFn->getArg(0)->getType());
- Builder.CreateCall(IFn, BC, "");
- }
- }
-}
-
/// This function inlines the called function into the basic block of the
/// caller. This returns false if it is not possible to inline this call.
/// The program is still in a well defined state if this occurs though.
@@ -1781,8 +1687,6 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
// ... and "funclet" operand bundles.
if (Tag == LLVMContext::OB_funclet)
continue;
- if (Tag == LLVMContext::OB_clang_arc_rv)
- continue;
return InlineResult::failure("unsupported operand bundle");
}
@@ -1949,10 +1853,6 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
// Remember the first block that is newly cloned over.
FirstNewBlock = LastBlock; ++FirstNewBlock;
- // Insert retainRV/clainRV runtime calls.
- if (objcarc::hasRVOpBundle(&CB))
- inlineRetainOrClaimRVCalls(CB, Returns);
-
if (IFI.CallerBFI != nullptr && IFI.CalleeBFI != nullptr)
// Update the BFI of blocks cloned into the caller.
updateCallerBFI(OrigBB, VMap, IFI.CallerBFI, IFI.CalleeBFI,
diff --git a/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll b/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll
index cb7a3ee7eb71..f22fcbeb271e 100644
--- a/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll
+++ b/llvm/test/Bitcode/operand-bundles-bc-analyzer.ll
@@ -9,7 +9,6 @@
; CHECK-NEXT: <OPERAND_BUNDLE_TAG
; CHECK-NEXT: <OPERAND_BUNDLE_TAG
; CHECK-NEXT: <OPERAND_BUNDLE_TAG
-; CHECK-NEXT: <OPERAND_BUNDLE_TAG
; CHECK-NEXT: </OPERAND_BUNDLE_TAGS_BLOCK
; CHECK: <FUNCTION_BLOCK
diff --git a/llvm/test/CodeGen/AArch64/call-rv-marker.ll b/llvm/test/CodeGen/AArch64/call-rv-marker.ll
index 7360c185bbbd..245d2c854c34 100644
--- a/llvm/test/CodeGen/AArch64/call-rv-marker.ll
+++ b/llvm/test/CodeGen/AArch64/call-rv-marker.ll
@@ -33,7 +33,7 @@ define dso_local i8* @rv_marker_1() {
; GISEL-NOT: mov x29, x29
;
entry:
- %call = call i8* @foo1() [ "clang.arc.rv"(i64 0) ]
+ %call = call "rv_marker" i8* @foo1()
ret i8* %call
}
@@ -49,7 +49,7 @@ define dso_local void @rv_marker_2_select(i32 %c) {
entry:
%tobool.not = icmp eq i32 %c, 0
%.sink = select i1 %tobool.not, i32 2, i32 1
- %call1 = call i8* @foo0(i32 %.sink) [ "clang.arc.rv"(i64 0) ]
+ %call1 = call "rv_marker" i8* @foo0(i32 %.sink)
tail call void @foo2(i8* %call1)
ret void
}
@@ -61,7 +61,7 @@ define dso_local void @rv_marker_3() personality i8* bitcast (i32 (...)* @__gxx_
; SELDAG-NEXT: mov x29, x29
;
entry:
- %call = call i8* @foo1() [ "clang.arc.rv"(i64 0) ]
+ %call = call "rv_marker" i8* @foo1()
invoke void @objc_object(i8* %call) #5
to label %invoke.cont unwind label %lpad
@@ -87,7 +87,7 @@ entry:
%s = alloca %struct.S, align 1
%0 = getelementptr inbounds %struct.S, %struct.S* %s, i64 0, i32 0
call void @llvm.lifetime.start.p0i8(i64 1, i8* nonnull %0) #2
- %call = invoke i8* @foo1() [ "clang.arc.rv"(i64 0) ]
+ %call = invoke "rv_marker" i8* @foo1()
to label %invoke.cont unwind label %lpad
invoke.cont: ; preds = %entry
@@ -127,7 +127,7 @@ define dso_local i8* @rv_marker_5_indirect_call() {
;
entry:
%0 = load i8* ()*, i8* ()** @fptr, align 8
- %call = call i8* %0() [ "clang.arc.rv"(i64 0) ]
+ %call = call "rv_marker" i8* %0()
tail call void @foo2(i8* %call)
ret i8* %call
}
@@ -142,7 +142,7 @@ define dso_local void @rv_marker_multiarg(i64 %a, i64 %b, i64 %c) {
; CHECK-NEXT: bl foo
; SELDAG-NEXT: mov x29, x29
; GISEL-NOT: mov x29, x29
- call void @foo(i64 %c, i64 %b, i64 %a) [ "clang.arc.rv"(i64 0) ]
+ call "rv_marker" void @foo(i64 %c, i64 %b, i64 %a)
ret void
}
diff --git a/llvm/test/Transforms/DeadArgElim/deadretval.ll b/llvm/test/Transforms/DeadArgElim/deadretval.ll
index 1eb0e6ecc186..5f3817c6728d 100644
--- a/llvm/test/Transforms/DeadArgElim/deadretval.ll
+++ b/llvm/test/Transforms/DeadArgElim/deadretval.ll
@@ -1,8 +1,4 @@
-; RUN: opt < %s -deadargelim -S | FileCheck %s
-
- at g0 = global i8 0, align 8
-
-; CHECK-NOT: DEAD
+; RUN: opt < %s -deadargelim -S | not grep DEAD
; Dead arg only used by dead retval
define internal i32 @test(i32 %DEADARG) {
@@ -20,22 +16,3 @@ define i32 @test3() {
ret i32 %Y
}
-; The callee function's return type shouldn't be changed if the call result is
-; used.
-
-; CHECK-LABEL: define internal i8* @callee4()
-
-define internal i8* @callee4(i8* %a0) {
- ret i8* @g0;
-}
-
-declare void @llvm.objc.clang.arc.noop.use(...)
-
-; CHECK-LABEL: define i8* @test4(
-; CHECK: tail call i8* @callee4() [ "clang.arc.rv"(i64 0) ]
-
-define i8* @test4() {
- %call = tail call i8* @callee4(i8* @g0) [ "clang.arc.rv"(i64 0) ]
- call void (...) @llvm.objc.clang.arc.noop.use(i8* %call)
- ret i8* @g0
-}
diff --git a/llvm/test/Transforms/Inline/inline-retainRV-call.ll b/llvm/test/Transforms/Inline/inline-retainRV-call.ll
deleted file mode 100644
index 243cf5453271..000000000000
--- a/llvm/test/Transforms/Inline/inline-retainRV-call.ll
+++ /dev/null
@@ -1,175 +0,0 @@
-; RUN: opt < %s -inline -S | FileCheck %s
-
- at g0 = global i8* null, align 8
-declare i8* @foo0()
-
-define i8* @callee0_autoreleaseRV() {
- %call = call i8* @foo0() [ "clang.arc.rv"(i64 0) ]
- %1 = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* %call)
- ret i8* %call
-}
-
-; CHECK-LABEL: define void @test0_autoreleaseRV(
-; CHECK: call i8* @foo0() [ "clang.arc.rv"(i64 0) ]
-
-define void @test0_autoreleaseRV() {
- %call = call i8* @callee0_autoreleaseRV() [ "clang.arc.rv"(i64 0) ]
- ret void
-}
-
-; CHECK-LABEL: define void @test0_claimRV_autoreleaseRV(
-; CHECK: %[[CALL:.*]] = call i8* @foo0() [ "clang.arc.rv"(i64 0) ]
-; CHECK: call void @llvm.objc.release(i8* %[[CALL]])
-; CHECK-NEXT: ret void
-
-define void @test0_claimRV_autoreleaseRV() {
- %call = call i8* @callee0_autoreleaseRV() [ "clang.arc.rv"(i64 1) ]
- ret void
-}
-
-; CHECK-LABEL: define void @test1_autoreleaseRV(
-; CHECK: invoke i8* @foo0() [ "clang.arc.rv"(i64 0) ]
-
-define void @test1_autoreleaseRV() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
-entry:
- %call = invoke i8* @callee0_autoreleaseRV() [ "clang.arc.rv"(i64 0) ]
- to label %invoke.cont unwind label %lpad
-
-invoke.cont:
- ret void
-
-lpad:
- %0 = landingpad { i8*, i32 }
- cleanup
- resume { i8*, i32 } undef
-}
-
-; CHECK-LABEL: define void @test1_claimRV_autoreleaseRV(
-; CHECK: %[[INVOKE:.*]] = invoke i8* @foo0() [ "clang.arc.rv"(i64 0) ]
-; CHECK: call void @llvm.objc.release(i8* %[[INVOKE]])
-; CHECK-NEXT: br
-
-define void @test1_claimRV_autoreleaseRV() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
-entry:
- %call = invoke i8* @callee0_autoreleaseRV() [ "clang.arc.rv"(i64 1) ]
- to label %invoke.cont unwind label %lpad
-
-invoke.cont:
- ret void
-
-lpad:
- %0 = landingpad { i8*, i32 }
- cleanup
- resume { i8*, i32 } undef
-}
-
-define i8* @callee1_no_autoreleaseRV() {
- %call = call i8* @foo0()
- ret i8* %call
-}
-
-; CHECK-LABEL: define void @test2_no_autoreleaseRV(
-; CHECK: call i8* @foo0() [ "clang.arc.rv"(i64 0) ]
-; CHECK-NEXT: ret void
-
-define void @test2_no_autoreleaseRV() {
- %call = call i8* @callee1_no_autoreleaseRV() [ "clang.arc.rv"(i64 0) ]
- ret void
-}
-
-; CHECK-LABEL: define void @test2_claimRV_no_autoreleaseRV(
-; CHECK: call i8* @foo0() [ "clang.arc.rv"(i64 1) ]
-; CHECK-NEXT: ret void
-
-define void @test2_claimRV_no_autoreleaseRV() {
- %call = call i8* @callee1_no_autoreleaseRV() [ "clang.arc.rv"(i64 1) ]
- ret void
-}
-
-; CHECK-LABEL: define void @test3_no_autoreleaseRV(
-; CHECK: invoke i8* @foo0() [ "clang.arc.rv"(i64 0) ]
-
-define void @test3_no_autoreleaseRV() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
-entry:
- %call = invoke i8* @callee1_no_autoreleaseRV() [ "clang.arc.rv"(i64 0) ]
- to label %invoke.cont unwind label %lpad
-
-invoke.cont:
- ret void
-
-lpad:
- %0 = landingpad { i8*, i32 }
- cleanup
- resume { i8*, i32 } undef
-}
-
-define i8* @callee2_nocall() {
- %1 = load i8*, i8** @g0, align 8
- ret i8* %1
-}
-
-; Check that a call to @llvm.objc.retain is inserted if there is no matching
-; autoreleaseRV call or a call.
-
-; CHECK-LABEL: define void @test4_nocall(
-; CHECK: %[[V0:.*]] = load i8*, i8** @g0,
-; CHECK-NEXT: call i8* @llvm.objc.retain(i8* %[[V0]])
-; CHECK-NEXT: ret void
-
-define void @test4_nocall() {
- %call = call i8* @callee2_nocall() [ "clang.arc.rv"(i64 0) ]
- ret void
-}
-
-; CHECK-LABEL: define void @test4_claimRV_nocall(
-; CHECK: %[[V0:.*]] = load i8*, i8** @g0,
-; CHECK-NEXT: ret void
-
-define void @test4_claimRV_nocall() {
- %call = call i8* @callee2_nocall() [ "clang.arc.rv"(i64 1) ]
- ret void
-}
-
-; Check that a call to @llvm.objc.retain is inserted if call to @foo already has
-; the attribute. I'm not sure this will happen in practice.
-
-define i8* @callee3_marker() {
- %1 = call i8* @foo0() [ "clang.arc.rv"(i64 0) ]
- ret i8* %1
-}
-
-; CHECK-LABEL: define void @test5(
-; CHECK: %[[V0:.*]] = call i8* @foo0() [ "clang.arc.rv"(i64 0) ]
-; CHECK-NEXT: call i8* @llvm.objc.retain(i8* %[[V0]])
-; CHECK-NEXT: ret void
-
-define void @test5() {
- %call = call i8* @callee3_marker() [ "clang.arc.rv"(i64 0) ]
- ret void
-}
-
-; Don't pair up an autoreleaseRV in the callee and an retainRV in the caller
-; if there is an instruction between the ret instruction and the call to
-; autoreleaseRV that isn't a cast instruction.
-
-define i8* @callee0_autoreleaseRV2() {
- %call = call i8* @foo0() [ "clang.arc.rv"(i64 0) ]
- %1 = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* %call)
- store i8* null, i8** @g0
- ret i8* %call
-}
-
-; CHECK-LABEL: define void @test6(
-; CHECK: %[[V0:.*]] = call i8* @foo0() [ "clang.arc.rv"(i64 0) ]
-; CHECK: call i8* @llvm.objc.autoreleaseReturnValue(i8* %[[V0]])
-; CHECK: store i8* null, i8** @g0, align 8
-; CHECK: call i8* @llvm.objc.retain(i8* %[[V0]])
-; CHECK-NEXT: ret void
-
-define void @test6() {
- %call = call i8* @callee0_autoreleaseRV2() [ "clang.arc.rv"(i64 0) ]
- ret void
-}
-
-declare i8* @llvm.objc.autoreleaseReturnValue(i8*)
-declare i32 @__gxx_personality_v0(...)
diff --git a/llvm/test/Transforms/ObjCARC/contract-marker-funclet.ll b/llvm/test/Transforms/ObjCARC/contract-marker-funclet.ll
index 799548646d54..c0d6e0033dda 100644
--- a/llvm/test/Transforms/ObjCARC/contract-marker-funclet.ll
+++ b/llvm/test/Transforms/ObjCARC/contract-marker-funclet.ll
@@ -10,16 +10,6 @@
; }
; }
-; CHECK-LABEL: define void @"\01?g@@YAXXZ"()
-; CHECK-LABEL: catch
-; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""() [ "funclet"(token %1) ]
-
-; CHECK-LABEL: catch.1
-; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""() [ "funclet"(token %1) ]
-
-; CHECK-LABEL: invoke.cont
-; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""(){{$}}
-
define void @"\01?g@@YAXXZ"() personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
entry:
%call = invoke i8* @"\01?f@@YAPAUobjc_object@@XZ"()
@@ -50,41 +40,23 @@ invoke.cont: ; preds = %entry
ret void
}
-; CHECK-LABEL: define dso_local void @"?test_attr_claimRV@@YAXXZ"()
-; CHECK: %[[CALL4:.*]] = notail call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() [ "clang.arc.rv"(i64 1) ]
-; CHECK: call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* %[[CALL4]])
-
-; CHECK: %[[V1:.*]] = cleanuppad
-; CHECK: %[[CALL:.*]] = notail call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() [ "funclet"(token %[[V1]]), "clang.arc.rv"(i64 1) ]
-; CHECK: call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* %[[CALL]]) [ "funclet"(token %[[V1]]) ]
-
-define dso_local void @"?test_attr_claimRV@@YAXXZ"() local_unnamed_addr #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
-entry:
- invoke void @"?foo@@YAXXZ"()
- to label %invoke.cont unwind label %ehcleanup
-
-invoke.cont: ; preds = %entry
- %call.i4 = tail call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() #2 [ "clang.arc.rv"(i64 1) ]
- ret void
-
-ehcleanup: ; preds = %entry
- %0 = cleanuppad within none []
- %call.i = call i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"() #2 [ "funclet"(token %0), "clang.arc.rv"(i64 1) ]
- cleanupret from %0 unwind to caller
-}
-
declare i8* @"\01?f@@YAPAUobjc_object@@XZ"()
declare i32 @__CxxFrameHandler3(...)
-declare void @"?foo@@YAXXZ"()
-declare i8* @"?noexcept_func@@YAPAUobjc_object@@XZ"()
-
declare dllimport i8* @llvm.objc.retainAutoreleasedReturnValue(i8*)
-declare i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8*)
declare dllimport void @llvm.objc.release(i8*)
!llvm.module.flags = !{!0}
!0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"movl\09%ebp, %ebp\09\09// marker for objc_retainAutoreleaseReturnValue"}
+
+; CHECK-LABEL: catch
+; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""() [ "funclet"(token %1) ]
+
+; CHECK-LABEL: catch.1
+; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""() [ "funclet"(token %1) ]
+
+; CHECK-LABEL: invoke.cont
+; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""(){{$}}
diff --git a/llvm/test/Transforms/ObjCARC/contract-rv-attr.ll b/llvm/test/Transforms/ObjCARC/contract-rv-attr.ll
deleted file mode 100644
index e460fb9c7e72..000000000000
--- a/llvm/test/Transforms/ObjCARC/contract-rv-attr.ll
+++ /dev/null
@@ -1,63 +0,0 @@
-; RUN: opt -objc-arc-contract -S < %s | FileCheck %s
-; RUN: opt -passes=objc-arc-contract -S < %s | FileCheck %s
-
-; CHECK-LABEL: define void @test0() {
-; CHECK: %[[CALL:.*]] = notail call i8* @foo() [ "clang.arc.rv"(i64 0) ]
-; CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL]])
-
-define void @test0() {
- %call1 = call i8* @foo() [ "clang.arc.rv"(i64 0) ]
- ret void
-}
-
-; CHECK-LABEL: define void @test1() {
-; CHECK: %[[CALL:.*]] = notail call i8* @foo() [ "clang.arc.rv"(i64 1) ]
-; CHECK: call i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8* %[[CALL]])
-
-define void @test1() {
- %call1 = call i8* @foo() [ "clang.arc.rv"(i64 1) ]
- ret void
-}
-
-; CHECK-LABEL:define i8* @test2(
-; CHECK: %[[CALL1:.*]] = invoke i8* @foo() [ "clang.arc.rv"(i64 0) ]
-
-; CHECK: %[[V0:.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL1]])
-; CHECK-NEXT: br
-
-; CHECK: %[[CALL3:.*]] = invoke i8* @foo() [ "clang.arc.rv"(i64 0) ]
-
-; CHECK: %[[V2:.*]] = call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL3]])
-; CHECK-NEXT: br
-
-; CHECK: %[[RETVAL:.*]] = phi i8* [ %[[V0]], {{.*}} ], [ %[[V2]], {{.*}} ]
-; CHECK: ret i8* %[[RETVAL]]
-
-define i8* @test2(i1 zeroext %b) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
-entry:
- br i1 %b, label %if.then, label %if.end
-
-if.then:
- %call1 = invoke i8* @foo() [ "clang.arc.rv"(i64 0) ]
- to label %cleanup unwind label %lpad
-
-lpad:
- %0 = landingpad { i8*, i32 }
- cleanup
- resume { i8*, i32 } undef
-
-if.end:
- %call3 = invoke i8* @foo() [ "clang.arc.rv"(i64 0) ]
- to label %cleanup unwind label %lpad
-
-cleanup:
- %retval.0 = phi i8* [ %call1, %if.then ], [ %call3, %if.end ]
- ret i8* %retval.0
-}
-
-declare i8* @foo()
-declare i32 @__gxx_personality_v0(...)
-
-!llvm.module.flags = !{!0}
-
-!0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov\09fp, fp\09\09// marker for objc_retainAutoreleaseReturnValue"}
diff --git a/llvm/test/Transforms/ObjCARC/contract.ll b/llvm/test/Transforms/ObjCARC/contract.ll
index 36f0a842d0e6..d62fe221529e 100644
--- a/llvm/test/Transforms/ObjCARC/contract.ll
+++ b/llvm/test/Transforms/ObjCARC/contract.ll
@@ -227,15 +227,7 @@ define void @test13() {
ret void
}
-; CHECK-LABEL: define void @test14(
-; CHECK-NOT: clang.arc.noop.use
-; CHECK: ret void
-define void @test14(i8* %a, i8* %b) {
- call void (...) @llvm.objc.clang.arc.noop.use(i8* %a, i8* %b) nounwind
- ret void
-}
declare void @llvm.objc.clang.arc.use(...) nounwind
-declare void @llvm.objc.clang.arc.noop.use(...) nounwind
; CHECK: attributes [[NUW]] = { nounwind }
diff --git a/llvm/test/Transforms/ObjCARC/intrinsic-use.ll b/llvm/test/Transforms/ObjCARC/intrinsic-use.ll
index bd4ac2965fb3..6f3815113d69 100644
--- a/llvm/test/Transforms/ObjCARC/intrinsic-use.ll
+++ b/llvm/test/Transforms/ObjCARC/intrinsic-use.ll
@@ -8,10 +8,8 @@ declare void @llvm.objc.release(i8*)
declare i8* @llvm.objc.autorelease(i8*)
declare void @llvm.objc.clang.arc.use(...)
-declare void @llvm.objc.clang.arc.noop.use(...)
declare void @test0_helper(i8*, i8**)
-declare void @can_release(i8*)
; Ensure that we honor clang.arc.use as a use and don't miscompile
; the reduced test case from <rdar://13195034>.
@@ -110,21 +108,6 @@ entry:
ret void
}
-; ARC optimizer should be able to safely remove the retain/release pair as the
-; call to @llvm.objc.clang.arc.noop.use is a no-op.
-
-; CHECK-LABEL: define void @test_arc_noop_use(
-; CHECK-NEXT: call void @can_release(i8* %x)
-; CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(
-; CHECK-NEXT: ret void
-
-define void @test_arc_noop_use(i8** %out, i8* %x) {
- call i8* @llvm.objc.retain(i8* %x)
- call void @can_release(i8* %x)
- call void (...) @llvm.objc.clang.arc.noop.use(i8* %x)
- call void @llvm.objc.release(i8* %x), !clang.imprecise_release !0
- ret void
-}
!0 = !{}
diff --git a/llvm/test/Transforms/ObjCARC/rv.ll b/llvm/test/Transforms/ObjCARC/rv.ll
index 07b6f73b2ab0..f89e9f7e39d9 100644
--- a/llvm/test/Transforms/ObjCARC/rv.ll
+++ b/llvm/test/Transforms/ObjCARC/rv.ll
@@ -452,29 +452,6 @@ bb1:
ret i8* %v3
}
-; Remove operand bundle "clang.arc.rv" and the autoreleaseRV call if the call
-; is a tail call.
-
-; CHECK-LABEL: define i8* @test31(
-; CHECK: %[[CALL:.*]] = tail call i8* @returner()
-; CHECK: ret i8* %[[CALL]]
-
-define i8* @test31() {
- %call = tail call i8* @returner() [ "clang.arc.rv"(i64 0) ]
- %1 = call i8* @llvm.objc.autoreleaseReturnValue(i8* %call)
- ret i8* %1
-}
-
-; CHECK-LABEL: define i8* @test32(
-; CHECK: %[[CALL:.*]] = call i8* @returner() [ "clang.arc.rv"(i64 0) ]
-; CHECK: call i8* @llvm.objc.autoreleaseReturnValue(i8* %[[CALL]])
-
-define i8* @test32() {
- %call = call i8* @returner() [ "clang.arc.rv"(i64 0) ]
- %1 = call i8* @llvm.objc.autoreleaseReturnValue(i8* %call)
- ret i8* %1
-}
-
!0 = !{}
; CHECK: attributes [[NUW]] = { nounwind }
diff --git a/llvm/test/Transforms/TailCallElim/operand-bundles.ll b/llvm/test/Transforms/TailCallElim/deopt-bundle.ll
similarity index 84%
rename from llvm/test/Transforms/TailCallElim/operand-bundles.ll
rename to llvm/test/Transforms/TailCallElim/deopt-bundle.ll
index ad168bc7251e..f651e462c1f5 100644
--- a/llvm/test/Transforms/TailCallElim/operand-bundles.ll
+++ b/llvm/test/Transforms/TailCallElim/deopt-bundle.ll
@@ -55,13 +55,3 @@ catch:
exit:
ret void
}
-
-; CHECK-LABEL: @test_clang_arc_rv(
-; CHECK: tail call i8* @getObj(
-
-declare i8* @getObj()
-
-define i8* @test_clang_arc_rv() {
- %r = call i8* @getObj() [ "clang.arc.rv"(i64 0) ]
- ret i8* %r
-}
More information about the cfe-commits
mailing list