Skip to content

Add support for "clang.arc.attachedcall" on x86-64 #3528

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions clang/lib/CodeGen/CGObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2354,9 +2354,12 @@ static llvm::Value *emitOptimizedARCReturnCall(llvm::Value *value,
: llvm::Intrinsic::objc_unsafeClaimAutoreleasedReturnValue;
EP = getARCIntrinsic(IID, CGF.CGM);

// FIXME: Do this when the target isn't aarch64.
llvm::Triple::ArchType Arch = CGF.CGM.getTriple().getArch();

// FIXME: Do this on all targets and at -O0 too. This can be enabled only if
// the target backend knows how to handle the operand bundle.
if (CGF.CGM.getCodeGenOpts().OptimizationLevel > 0 &&
CGF.CGM.getTarget().getTriple().isAArch64()) {
(Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::x86_64)) {
llvm::Value *bundleArgs[] = {EP};
llvm::OperandBundleDef OB("clang.arc.attachedcall", bundleArgs);
auto *oldCall = cast<llvm::CallBase>(value);
Expand Down
22 changes: 11 additions & 11 deletions clang/test/CodeGenObjC/arc-blocks.m
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@ void test4(void) {
// 0x02000000 - has copy/dispose helpers strong
// CHECK-NEXT: store i32 838860800, i32* [[T0]]
// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
// CHECK-NEXT: [[T0:%.*]] = call i8* @test4_source()
// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]]
// CHECK-NEXT: [[T0:%.*]] = call i8* @test4_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]])
// CHECK-NEXT: store i8* [[T0]], i8** [[SLOT]]
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
// 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT
// CHECK: store i32 -1040187392,
Expand Down Expand Up @@ -180,8 +180,8 @@ void test5(void) {
// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
// CHECK-NEXT: [[VARPTR1:%.*]] = bitcast i8** [[VAR]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[VARPTR1]])
// CHECK: [[T0:%.*]] = call i8* @test5_source()
// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK: [[T1:%.*]] = call i8* @test5_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
// CHECK-NEXT: store i8* [[T1]], i8** [[VAR]],
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
// 0x40800000 - has signature but no copy/dispose, as well as BLOCK_HAS_EXTENDED_LAYOUT
Expand Down Expand Up @@ -211,8 +211,8 @@ void test6(void) {
// 0x02000000 - has copy/dispose helpers weak
// CHECK-NEXT: store i32 1107296256, i32* [[T0]]
// CHECK: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
// CHECK-NEXT: [[T0:%.*]] = call i8* @test6_source()
// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: [[T1:%.*]] = call i8* @test6_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[SLOT]], i8* [[T1]])
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
// CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [[BYREF_T]], [[BYREF_T]]* [[VAR]], i32 0, i32 6
Expand Down Expand Up @@ -257,8 +257,8 @@ void test7(void) {
// CHECK-LABEL: define{{.*}} void @test7()
// CHECK: [[VAR:%.*]] = alloca i8*,
// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
// CHECK: [[T0:%.*]] = call i8* @test7_source()
// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK: [[T1:%.*]] = call i8* @test7_source() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]])
// CHECK-NEXT: call i8* @llvm.objc.initWeak(i8** [[VAR]], i8* [[T1]])
// CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]])
// 0x42800000 - has signature, copy/dispose helpers, as well as BLOCK_HAS_EXTENDED_LAYOUT
Expand Down Expand Up @@ -325,8 +325,8 @@ id test9(void) {
// CHECK-NEXT: tail call i8* @llvm.objc.autoreleaseReturnValue
// CHECK-NEXT: ret i8*

// CHECK: call i8* @test9_produce()
// CHECK-NEXT: call i8* @llvm.objc.retain
// CHECK: call i8* @test9_produce() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(
// CHECK-NEXT: ret i8*
}

Expand Down
12 changes: 4 additions & 8 deletions clang/test/CodeGenObjC/arc-bridged-cast.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ void bridge_transfer_from_cf(int *i) {
void bridge_from_cf(int *i) {
// CHECK: store i32 7
*i = 7;
// CHECK: call i8* @CFCreateSomething()
// CHECK: call i8* @CFCreateSomething() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
id obj1 = (__bridge id)CFCreateSomething();
// CHECK: llvm.objc.retainAutoreleasedReturnValue
// CHECK: store i32 11
*i = 11;
// CHECK: call i8* @CFCreateSomething()
Expand All @@ -60,14 +59,12 @@ void bridge_from_cf(int *i) {
// CHECK-LABEL: define{{.*}} void @bridge_retained_of_cf
void bridge_retained_of_cf(int *i) {
*i = 7;
// CHECK: call i8* @CreateSomething()
// CHECK: call i8* @CreateSomething() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
CFTypeRef cf1 = (__bridge_retained CFTypeRef)CreateSomething();
// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue
// CHECK: store i32 11
*i = 11;
// CHECK: call i8* @CreateSomething()
// CHECK: call i8* @CreateSomething() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
(__bridge_retained CFTypeRef)CreateSomething(), *i = 13;
// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue
// CHECK: store i32 13
// CHECK: store i32 17
*i = 17;
Expand Down Expand Up @@ -99,8 +96,7 @@ void bridge_of_cf(int *i) {

// CHECK-LABEL: define{{.*}} %struct.__CFString* @bridge_of_paren_expr()
CFStringRef bridge_of_paren_expr() {
// CHECK-NOT: call i8* @llvm.objc.retainAutoreleasedReturnValue(
// CHECK-NOT: call void @llvm.objc.release(
// CHECK-NOT: "@llvm.objc"
CFStringRef r = (__bridge CFStringRef)(CreateNSString());
r = (__bridge CFStringRef)((NSString *)(CreateNSString()));
return r;
Expand Down
29 changes: 11 additions & 18 deletions clang/test/CodeGenObjC/arc-literals.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,13 @@

// CHECK-LABEL: define{{.*}} void @test_numeric()
void test_numeric() {
// CHECK: {{call.*objc_msgSend.*i32 17}}
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
// CHECK: {{call.*objc_msgSend.*i32 17.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}}
id ilit = @17;
// CHECK: {{call.*objc_msgSend.*i32 25}}
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
// CHECK: {{call.*objc_msgSend.*i32 25.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}}
id ulit = @25u;
// CHECK: {{call.*objc_msgSend.*i64 42}}
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
// CHECK: {{call.*objc_msgSend.*i64 42.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}}
id ulllit = @42ull;
// CHECK: {{call.*objc_msgSend.*i8 signext 97}}
// CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue
// CHECK: {{call.*objc_msgSend.*i8 signext 97.* [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]}}
id charlit = @'a';
// CHECK: call void @llvm.objc.release
// CHECK: call void @llvm.lifetime.end
Expand Down Expand Up @@ -58,8 +54,7 @@ void test_array(id a, id b) {
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
// CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 2)
// CHECK-NEXT: [[T4:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]])
// CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 2) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK: call void (...) @llvm.objc.clang.arc.use(i8* [[V0]], i8* [[V1]])
id arr = @[a, b];

Expand Down Expand Up @@ -102,8 +97,8 @@ void test_dictionary(id k1, id o1, id k2, id o2) {
// CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = bitcast [2 x i8*]* [[OBJECTS]] to i8**
// CHECK-NEXT: [[T3:%.*]] = bitcast [2 x i8*]* [[KEYS]] to i8**
// CHECK-NEXT: [[T4:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i8** [[T3]], i64 2)
// CHECK-NEXT: [[T5:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]])
// CHECK-NEXT: [[T4:%.*]] = call i8* bitcast ({{.*@objc_msgSend.*}})(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i8** [[T3]], i64 2) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T4]])
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[V0]], i8* [[V1]], i8* [[V2]], i8* [[V3]])

id dict = @{ k1 : o1, k2 : o2 };
Expand Down Expand Up @@ -133,10 +128,8 @@ void test_property(B *b) {
// Invoke 'prop'
// CHECK: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T1:%.*]] = bitcast
// CHECK-NEXT: [[T2:%.*]] = call [[B:%.*]]* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]])
// CHECK-NEXT: [[T3:%.*]] = bitcast [[B]]* [[T2]] to i8*
// CHECK-NEXT: [[T4:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]])
// CHECK-NEXT: [[V0:%.*]] = bitcast i8* [[T4]] to [[B]]*
// CHECK-NEXT: [[V0:%.*]] = call [[B:%.*]]* bitcast ({{.*}} @objc_msgSend to {{.*}})(i8* [[T1]], i8* [[SEL]]) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[B]]* [[V0]])
// CHECK-NEXT: [[V1:%.*]] = bitcast [[B]]* [[V0]] to i8*

// Store to array.
Expand All @@ -147,8 +140,8 @@ void test_property(B *b) {
// CHECK-NEXT: [[SEL:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES
// CHECK-NEXT: [[T1:%.*]] = bitcast [[CLASS_T]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = bitcast [1 x i8*]* [[OBJECTS]] to i8**
// CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}}(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 1)
// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T3]])
// CHECK-NEXT: [[T3:%.*]] = call i8* bitcast ({{.*}} @objc_msgSend to {{.*}}(i8* [[T1]], i8* [[SEL]], i8** [[T2]], i64 1) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T3]])
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.use(i8* [[V1]])
// CHECK-NEXT: bitcast
// CHECK-NEXT: bitcast
Expand Down
64 changes: 24 additions & 40 deletions clang/test/CodeGenObjC/arc-precise-lifetime.m
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,9 @@ void test1a_message(void) {
// CHECK: [[C:%.*]] = alloca i8*, align 8
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
// CHECK-NEXT: store [[TEST1]]* [[T0]]
// CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]])
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
Expand Down Expand Up @@ -75,11 +73,9 @@ void test1a_property(void) {
// CHECK: [[C:%.*]] = alloca i8*, align 8
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
// CHECK-NEXT: store [[TEST1]]* [[T0]]
// CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]])
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
Expand Down Expand Up @@ -109,11 +105,9 @@ void test1b_message(void) {
// CHECK: [[C:%.*]] = alloca i8*, align 8
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
// CHECK-NEXT: store [[TEST1]]* [[T0]]
// CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]])
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
Expand All @@ -140,11 +134,9 @@ void test1b_property(void) {
// CHECK: [[C:%.*]] = alloca i8*, align 8
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
// CHECK-NEXT: store [[TEST1]]* [[T0]]
// CHECK-NEXT: [[CPTR1:%.*]] = bitcast i8** [[C]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CPTR1]])
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
Expand All @@ -171,11 +163,9 @@ void test1c_message(void) {
// CHECK: [[PC:%.*]] = alloca i8*, align 8
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
// CHECK-NEXT: store [[TEST1]]* [[T0]]
// CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]])
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
Expand Down Expand Up @@ -204,11 +194,9 @@ void test1c_property(void) {
// CHECK: [[PC:%.*]] = alloca i8*, align 8
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
// CHECK-NEXT: store [[TEST1]]* [[T0]]
// CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]])
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
Expand Down Expand Up @@ -237,11 +225,9 @@ void test1d_message(void) {
// CHECK: [[PC:%.*]] = alloca i8*, align 8
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
// CHECK-NEXT: store [[TEST1]]* [[T0]]
// CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]])
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
Expand All @@ -267,11 +253,9 @@ void test1d_property(void) {
// CHECK: [[PC:%.*]] = alloca i8*, align 8
// CHECK: [[PTRPTR1:%.*]] = bitcast [[PTR_T]]** [[PTR]] to i8*
// CHECK: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTRPTR1]])
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper()
// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]])
// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST1]]*
// CHECK-NEXT: store [[TEST1]]* [[T3]]
// CHECK: [[T0:%.*]] = call [[TEST1:%.*]]* @test1_helper() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ]
// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST1]]* [[T0]])
// CHECK-NEXT: store [[TEST1]]* [[T0]]
// CHECK-NEXT: [[PCPTR1:%.*]] = bitcast i8** [[PC]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PCPTR1]])
// CHECK-NEXT: [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]**
Expand Down
1 change: 1 addition & 0 deletions clang/test/CodeGenObjC/arc-rv-attr.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// 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
// RUN: %clang_cc1 -triple x86_64-apple-macosx10 -fobjc-runtime=ios-9.0 -fobjc-arc -O -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK

@class A;

Expand Down
Loading