diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -2354,9 +2354,12 @@ : 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(value); diff --git a/clang/test/CodeGenObjC/arc-blocks.m b/clang/test/CodeGenObjC/arc-blocks.m --- a/clang/test/CodeGenObjC/arc-blocks.m +++ b/clang/test/CodeGenObjC/arc-blocks.m @@ -126,9 +126,9 @@ // 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, @@ -180,8 +180,8 @@ // 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 @@ -211,8 +211,8 @@ // 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 @@ -257,8 +257,8 @@ // 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 @@ -325,8 +325,8 @@ // 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* } diff --git a/clang/test/CodeGenObjC/arc-bridged-cast.m b/clang/test/CodeGenObjC/arc-bridged-cast.m --- a/clang/test/CodeGenObjC/arc-bridged-cast.m +++ b/clang/test/CodeGenObjC/arc-bridged-cast.m @@ -40,9 +40,8 @@ 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() @@ -60,14 +59,12 @@ // 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; @@ -99,8 +96,7 @@ // 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; diff --git a/clang/test/CodeGenObjC/arc-literals.m b/clang/test/CodeGenObjC/arc-literals.m --- a/clang/test/CodeGenObjC/arc-literals.m +++ b/clang/test/CodeGenObjC/arc-literals.m @@ -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 @@ -58,8 +54,7 @@ // 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]; @@ -102,8 +97,8 @@ // 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 }; @@ -133,10 +128,8 @@ // 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. @@ -147,8 +140,8 @@ // 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 diff --git a/clang/test/CodeGenObjC/arc-precise-lifetime.m b/clang/test/CodeGenObjC/arc-precise-lifetime.m --- a/clang/test/CodeGenObjC/arc-precise-lifetime.m +++ b/clang/test/CodeGenObjC/arc-precise-lifetime.m @@ -41,11 +41,9 @@ // 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]]** @@ -75,11 +73,9 @@ // 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]]** @@ -109,11 +105,9 @@ // 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]]** @@ -140,11 +134,9 @@ // 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]]** @@ -171,11 +163,9 @@ // 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]]** @@ -204,11 +194,9 @@ // 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]]** @@ -237,11 +225,9 @@ // 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]]** @@ -267,11 +253,9 @@ // 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]]** diff --git a/clang/test/CodeGenObjC/arc-rv-attr.m b/clang/test/CodeGenObjC/arc-rv-attr.m --- a/clang/test/CodeGenObjC/arc-rv-attr.m +++ b/clang/test/CodeGenObjC/arc-rv-attr.m @@ -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; diff --git a/clang/test/CodeGenObjC/arc-ternary-op.m b/clang/test/CodeGenObjC/arc-ternary-op.m --- a/clang/test/CodeGenObjC/arc-ternary-op.m +++ b/clang/test/CodeGenObjC/arc-ternary-op.m @@ -131,8 +131,8 @@ // CHECK-NEXT: store i1 false, i1* [[RUN_CLEANUP]] // CHECK-NEXT: br i1 // Within true branch, cleanup enabled. - // CHECK: [[T0:%.*]] = call i8* @test2_producer() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @test2_producer() [ "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** [[CLEANUP_SAVE]] // CHECK-NEXT: store i1 true, i1* [[RUN_CLEANUP]] // CHECK-NEXT: br label diff --git a/clang/test/CodeGenObjC/arc-unsafeclaim.m b/clang/test/CodeGenObjC/arc-unsafeclaim.m --- a/clang/test/CodeGenObjC/arc-unsafeclaim.m +++ b/clang/test/CodeGenObjC/arc-unsafeclaim.m @@ -1,6 +1,8 @@ // Make sure it works on x86-64. // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime=macosx-10.11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-UNOPTIMIZED -check-prefix=NOTAIL-CALL +// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime=macosx-10.11 -fobjc-arc -emit-llvm -O2 -disable-llvm-passes -o - %s | FileCheck %s -check-prefix=ATTACHED-CALL + // 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 @@ -43,6 +45,10 @@ // DISABLED-NEXT: [[T1:%.*]] = bitcast [[A]]* [[T0]] to i8* // DISABLED-NEXT: [[T2:%.*]] = {{.*}}call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) +// ATTACHED-CALL-LABEL: define{{.*}} void @test_assign() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_assign_assign() { __unsafe_unretained id x, y; x = y = makeA(); @@ -65,6 +71,10 @@ // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_assign_assign() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_strong_assign_assign() { __strong id x; __unsafe_unretained id y; @@ -92,6 +102,10 @@ // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_strong_assign_assign() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_assign_strong_assign() { __unsafe_unretained id x; __strong id y; @@ -119,6 +133,10 @@ // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_assign_strong_assign() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_init() { __unsafe_unretained id x = makeA(); } @@ -136,6 +154,10 @@ // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_init() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_init_assignment() { __unsafe_unretained id x; __unsafe_unretained id y = x = makeA(); @@ -158,6 +180,10 @@ // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_init_assignment() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_strong_init_assignment() { __unsafe_unretained id x; __strong id y = x = makeA(); @@ -182,6 +208,10 @@ // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_strong_init_assignment() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_init_strong_assignment() { __strong id x; __unsafe_unretained id y = x = makeA(); @@ -208,6 +238,10 @@ // CHECK-OPTIMIZED-NEXT: lifetime.end // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_init_strong_assignment() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_ignored() { makeA(); } @@ -220,6 +254,10 @@ // CHECK-NEXT: bitcast i8* [[T2]] to [[A]]* // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_ignored() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) + void test_cast_to_void() { (void) makeA(); } @@ -232,6 +270,9 @@ // CHECK-NEXT: bitcast i8* [[T2]] to [[A]]* // CHECK-NEXT: ret void +// ATTACHED-CALL-LABEL: define{{.*}} void @test_cast_to_void() +// ATTACHED-CALL: [[T0:%.*]] = call [[A:.*]]* @makeA() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.unsafeClaimAutoreleasedReturnValue) ], +// ATTACHED-CALL: call void (...) @llvm.objc.clang.arc.noop.use([[A]]* [[T0]]) // This is always at the end of the module. diff --git a/clang/test/CodeGenObjC/arc.m b/clang/test/CodeGenObjC/arc.m --- a/clang/test/CodeGenObjC/arc.m +++ b/clang/test/CodeGenObjC/arc.m @@ -316,16 +316,12 @@ // CHECK-NEXT: load [[TEST10]]*, [[TEST10]]** [[X]], align // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_{{[0-9]*}} // CHECK-NEXT: bitcast - // CHECK-NEXT: [[T0:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST10]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) - // CHECK-NEXT: [[V:%.*]] = bitcast i8* [[T2]] to [[TEST10]]* + // CHECK-NEXT: [[V:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(%3* [[V]]) // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_{{[0-9]*}} // CHECK-NEXT: bitcast - // CHECK-NEXT: [[T0:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend - // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST10]]* [[T0]] to i8* - // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) - // CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST10]]* + // CHECK-NEXT: [[T3:%.*]] = call [[TEST10]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(%3* [[T3]]) // CHECK-NEXT: [[T4:%.*]] = bitcast [[TEST10]]* [[T3]] to i8* // CHECK-NEXT: store i8* [[T4]], i8** [[Y]] // CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST10]]* [[V]] to i8* @@ -370,14 +366,14 @@ __weak id x = test12_helper(); // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) - // CHECK-NEXT: [[T0:%.*]] = call i8* @test12_helper() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @test12_helper(){{.*}} [ "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** [[X]], i8* [[T1]]) // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) x = test12_helper(); - // CHECK-NEXT: [[T0:%.*]] = call i8* @test12_helper() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @test12_helper(){{.*}} [ "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.storeWeak(i8** [[X]], i8* [[T1]]) // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) @@ -513,8 +509,8 @@ extern id test19_helper(void); x[2] = test19_helper(); - // CHECK-NEXT: [[CALL:%.*]] = call i8* @test19_helper() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]]) [[NUW]] + // CHECK-NEXT: [[T1:%.*]] = call i8* @test19_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: [[SLOT:%.*]] = getelementptr inbounds [5 x i8*], [5 x i8*]* [[X]], i64 0, i64 2 // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[SLOT]] // CHECK-NEXT: store i8* [[T1]], i8** [[SLOT]] @@ -875,8 +871,8 @@ __attribute__((ns_returns_retained)) id test32(void) { // CHECK-LABEL: define{{.*}} i8* @test32() -// CHECK: [[CALL:%.*]] = call i8* @test32_helper() -// CHECK-NEXT: [[T0:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]]) +// CHECK: [[T0:%.*]] = call i8* @test32_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]]) // CHECK-NEXT: ret i8* [[T0]] extern id test32_helper(void); return test32_helper(); @@ -1044,8 +1040,8 @@ - (id) test __attribute__((ns_returns_retained)) { extern id test43_produce(void); return test43_produce(); - // CHECK: call i8* @test43_produce() - // CHECK-NEXT: notail call i8* @llvm.objc.retainAutoreleasedReturnValue( + // CHECK: call i8* @test43_produce(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use( // CHECK-NEXT: ret } @end @@ -1066,8 +1062,8 @@ // TODO: this is sub-optimal, we should retain at the actual call site. - // CHECK: [[T0:%.*]] = call i8* @test46_helper() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @test46_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8 // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]]) // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retain(i8* [[T3]]) @@ -1075,8 +1071,8 @@ // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) id x = *wp = test46_helper(); - // CHECK: [[T0:%.*]] = call i8* @test46_helper() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @test46_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8 // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]]) // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retain(i8* [[T3]]) @@ -1095,8 +1091,8 @@ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) // CHECK-NEXT: store i8* null, i8** [[X]] - // CHECK-NEXT: [[CALL:%.*]] = call i8* @test47_helper() - // CHECK-NEXT: [[T0:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]]) + // CHECK-NEXT: [[T0:%.*]] = call i8* @test47_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]]) // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[X]] // CHECK-NEXT: store i8* [[T0]], i8** [[X]] // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) @@ -1119,8 +1115,8 @@ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.objc.initWeak(i8** [[X]], i8* null) - // CHECK-NEXT: [[T1:%.*]] = call i8* @test48_helper() - // CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) + // CHECK-NEXT: [[T2:%.*]] = call i8* @test48_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T2]]) // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[X]], i8* [[T2]]) // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[X]], i8* [[T3]]) // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) @@ -1138,10 +1134,10 @@ // CHECK-NEXT: [[XPTR1:%.*]] = bitcast i8** [[X]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) // CHECK-NEXT: store i8* null, i8** [[X]] - // CHECK-NEXT: [[CALL:%.*]] = call i8* @test49_helper() - // CHECK-NEXT: [[T0:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[CALL]]) + // CHECK-NEXT: [[T0:%.*]] = call i8* @test49_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]]) // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.autorelease(i8* [[T0]]) - // CHECK-NEXT: store i8* [[T2]], i8** [[X]] + // CHECK-NEXT: store i8* [[T1]], i8** [[X]] // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.retainAutorelease(i8* [[T1]]) // CHECK-NEXT: store i8* [[T3]], i8** [[X]] // CHECK-NEXT: [[XPTR2:%.*]] = bitcast i8** [[X]] to i8* @@ -1207,8 +1203,8 @@ // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[XPTR1]]) // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]]) -// CHECK-NEXT: [[T0:%.*]] = call i8* @test53_helper() -// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @test53_helper(){{.*}} [ "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** [[Y]], // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[Y]], // CHECK-NEXT: [[T1:%.*]] = call i8* @llvm.objc.retain(i8* [[T0]]) @@ -1260,8 +1256,8 @@ // CHECK: define internal i8* @"\01+[Test56 make]"( + (id) make { extern id test56_helper(void); - // CHECK: [[T0:%.*]] = call i8* @test56_helper() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @test56_helper(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: ret i8* [[T1]] return test56_helper(); } @@ -1327,8 +1323,8 @@ } // CHECK-LABEL: define{{.*}} void @test59() - // CHECK: [[T0:%.*]] = call i8* @test59_getlock() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @test59_getlock(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: call i32 @objc_sync_enter(i8* [[T1]]) // CHECK-NEXT: call void @test59_body() // CHECK-NEXT: call i32 @objc_sync_exit(i8* [[T1]]) @@ -1349,8 +1345,8 @@ extern id test61_make(void); - // CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]]) // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T1]], i8* [[T3]], i8* [[T2]]) @@ -1359,12 +1355,12 @@ // CHECK-NEXT: [[YPTR1:%.*]] = bitcast i8** [[Y]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[YPTR1]]) - // CHECK-NEXT: [[T0:%.*]] = call i8* @test61_make() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK-NEXT: [[T1:%.*]] = call i8* @test61_make(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ // CHECK-NEXT: [[T3:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_ - // CHECK-NEXT: [[T4:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T1]], i8* [[T3]], i8* [[T2]]) - // CHECK-NEXT: [[T5:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]]) + // CHECK-NEXT: [[T5:%.*]] = call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*, i8*)*)(i8* [[T1]], i8* [[T3]], i8* [[T2]]){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T5]]) // CHECK-NEXT: store i8* [[T5]], i8** [[Y]] // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) id y = [test61_make() performSelector: @selector(test61_id)]; @@ -1399,8 +1395,8 @@ // CHECK-NEXT: [[T1:%.*]] = icmp ne i32 [[T0]], 0 // CHECK-NEXT: store i1 false, i1* [[CLEANUP_REQUIRED]] // CHECK-NEXT: br i1 [[T1]], - // CHECK: [[T0:%.*]] = call i8* @test62_make() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @test62_make(){{.*}} [ "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** [[CLEANUP_VALUE]] // CHECK-NEXT: store i1 true, i1* [[CLEANUP_REQUIRED]] // CHECK-NEXT: [[T2:%.*]] = icmp ne i8* [[T1]], null @@ -1453,19 +1449,17 @@ [test66_receiver() consume: test66_arg()]; } // CHECK-LABEL: define{{.*}} void @test66() -// CHECK: [[T0:%.*]] = call [[TEST66:%.*]]* @test66_receiver() -// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST66]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) -// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[TEST66]]* -// CHECK-NEXT: [[T4:%.*]] = call i8* @test66_arg() -// CHECK-NEXT: [[T5:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T4]]) +// CHECK: [[T3:%.*]] = call [[TEST66:%.*]]* @test66_receiver(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use([[TEST66]]* [[T3]]) +// CHECK-NEXT: [[T4:%.*]] = call i8* @test66_arg(){{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T4]]) // CHECK-NEXT: [[T6:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES // CHECK-NEXT: [[T7:%.*]] = bitcast [[TEST66]]* [[T3]] to i8* // CHECK-NEXT: [[SIX:%.*]] = icmp eq i8* [[T7]], null // CHECK-NEXT: br i1 [[SIX]], label [[NULINIT:%.*]], label [[CALL:%.*]] -// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*)*)(i8* [[T7]], i8* [[T6]], i8* [[T5]]) +// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*)*)(i8* [[T7]], i8* [[T6]], i8* [[T4]]) // CHECK-NEXT: br label [[CONT:%.*]] -// CHECK: call void @llvm.objc.release(i8* [[T5]]) [[NUW]] +// CHECK: call void @llvm.objc.release(i8* [[T4]]) [[NUW]] // CHECK-NEXT: br label [[CONT:%.*]] // CHECK: [[T8:%.*]] = bitcast [[TEST66]]* [[T3]] to i8* // CHECK-NEXT: call void @llvm.objc.release(i8* [[T8]]) @@ -1494,8 +1488,8 @@ // CHECK: [[CL:%.*]] = alloca i8*, align 8 // CHECK-NEXT: [[CLPTR1:%.*]] = bitcast i8** [[CL]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[CLPTR1]]) -// CHECK-NEXT: [[T0:%.*]] = call i8* @test67_helper() -// CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) +// CHECK-NEXT: [[T1:%.*]] = call i8* @test67_helper(){{.*}} [ "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** [[CL]], align 8 // CHECK-NEXT: [[T2:%.*]] = load i8*, i8** [[CL]] // CHECK-NEXT: call void @llvm.objc.release(i8* [[T2]]) diff --git a/clang/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m b/clang/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m --- a/clang/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m +++ b/clang/test/CodeGenObjC/nsvalue-objc-boxable-mac-arc.m @@ -24,8 +24,7 @@ // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* NSRange ns_range = { .location = 0, .length = 42 }; - // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] NSValue *range = @(ns_range); // CHECK: call void @llvm.objc.release // CHECK: ret void @@ -43,8 +42,7 @@ // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* NSPoint ns_point = { .x = 42, .y = 24 }; - // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[POINT_STR]]{{.*}}) - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[POINT_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] NSValue *point = @(ns_point); // CHECK: call void @llvm.objc.release // CHECK: ret void @@ -62,8 +60,7 @@ // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* NSSize ns_size = { .width = 42, .height = 24 }; - // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[SIZE_STR]]{{.*}}) - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8* {{.*}}[[SIZE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] NSValue *size = @(ns_size); // CHECK: call void @llvm.objc.release // CHECK: ret void @@ -83,8 +80,7 @@ NSPoint ns_point = { .x = 42, .y = 24 }; NSSize ns_size = { .width = 42, .height = 24 }; NSRect ns_rect = { .origin = ns_point, .size = ns_size }; - // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8*{{.*}}[[RECT_STR]]{{.*}}) - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8*{{.*}}[[RECT_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] NSValue *rect = @(ns_rect); // CHECK: call void @llvm.objc.release // CHECK: ret void @@ -102,8 +98,7 @@ // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* NSEdgeInsets ns_edge_insets; - // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8*{{.*}}[[EDGE_STR]]{{.*}}) - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[PARAM_CAST]], i8*{{.*}}[[EDGE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] NSValue *edge_insets = @(ns_edge_insets); // CHECK: call void @llvm.objc.release // CHECK: ret void @@ -121,8 +116,7 @@ // CHECK: [[COERCE_CAST:%.*]] = bitcast %struct._NSRange* [[COERCE]]{{.*}} // CHECK: [[SEL:%.*]] = load i8*, i8** [[VALUE_SEL]] // CHECK: [[RECV:%.*]] = bitcast %struct._class_t* [[RECV_PTR]] to i8* - // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[COERCE_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call {{.*objc_msgSend.*}}(i8* [[RECV]], i8* [[SEL]], i8* [[COERCE_CAST]], i8* {{.*}}[[RANGE_STR]]{{.*}}) [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] NSValue *range_rvalue = @(getRange()); // CHECK: call void @llvm.objc.release // CHECK: ret void diff --git a/clang/test/CodeGenObjC/os_log.m b/clang/test/CodeGenObjC/os_log.m --- a/clang/test/CodeGenObjC/os_log.m +++ b/clang/test/CodeGenObjC/os_log.m @@ -26,10 +26,11 @@ // CHECK-O2: %[[V0:.*]] = call i8* @llvm.objc.retain( // CHECK-O2: store i8* %[[V0]], i8** %[[A_ADDR]], align 8, // CHECK-O0: call void @llvm.objc.storeStrong(i8** %[[A_ADDR]], i8* %{{.*}}) -// CHECK: %[[CALL:.*]] = call %{{.*}}* (...) @GenString() -// CHECK: %[[V2:.*]] = bitcast %{{.*}}* %[[CALL]] to i8* -// CHECK: %[[V3:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V2]]) -// CHECK: %[[V4:.*]] = bitcast i8* %[[V3]] to %{{.*}}* +// CHECK-O2: %[[V4:.*]] = call %{{.*}}* (...) @GenString() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-O0: %[[CALL:.*]] = call %{{.*}}* (...) @GenString() +// CHECK-O0: %[[V2:.*]] = bitcast %{{.*}}* %[[CALL]] to i8* +// CHECK-O0: %[[V3:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V2]]) +// CHECK-O0: %[[V4:.*]] = bitcast i8* %[[V3]] to %{{.*}}* // CHECK: %[[V5:.*]] = bitcast %{{.*}}* %[[V4]] to i8* // CHECK: %[[V6:.*]] = call i8* @llvm.objc.retain(i8* %[[V5]]) // CHECK: %[[V7:.*]] = bitcast i8* %[[V6]] to %{{.*}}* @@ -71,10 +72,11 @@ // CHECK-LABEL: define{{.*}} void @test_builtin_os_log3( // CHECK: alloca i8*, align 8 // CHECK: %[[OS_LOG_ARG:.*]] = alloca i8*, align 8 -// CHECK: %[[CALL:.*]] = call %{{.*}}* (...) @GenString() -// CHECK: %[[V1:.*]] = bitcast %{{.*}}* %[[CALL]] to i8* -// CHECK: %[[V2:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V1]]) -// CHECK: %[[V3:.*]] = bitcast i8* %[[V2]] to %{{.*}}* +// CHECK-O2: %[[V3:.*]] = call %{{.*}}* (...) @GenString() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-O0: %[[CALL:.*]] = call %{{.*}}* (...) @GenString() +// CHECK-O0: %[[V1:.*]] = bitcast %{{.*}}* %[[CALL]] to i8* +// CHECK-O0: %[[V2:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[V1]]) +// CHECK-O0: %[[V3:.*]] = bitcast i8* %[[V2]] to %{{.*}}* // CHECK: %[[V4:.*]] = bitcast %{{.*}}* %[[V3]] to i8* // CHECK: %[[V5:.*]] = call i8* @llvm.objc.retain(i8* %[[V4]]) // CHECK: store i8* %[[V5]], i8** %[[OS_LOG_ARG]], align 8 @@ -97,13 +99,15 @@ // CHECK: alloca i8*, align 8 // CHECK: %[[OS_LOG_ARG:.*]] = alloca i8*, align 8 // CHECK: %[[OS_LOG_ARG2:.*]] = alloca i8*, align 8 -// CHECK: %[[CALL:.*]] = call {{.*}} @objc_msgSend -// CHECK: %[[V4:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL]]) +// CHECK-O2: %[[V4:.*]] = call {{.*}} @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-O0: %[[CALL:.*]] = call {{.*}} @objc_msgSend +// CHECK-O0: %[[V4:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL]]) // CHECK: %[[V5:.*]] = call i8* @llvm.objc.retain(i8* %[[V4]]) // CHECK: store i8* %[[V5]], i8** %[[OS_LOG_ARG]], align 8 // CHECK: %[[V6:.*]] = ptrtoint i8* %[[V5]] to i64 -// CHECK: %[[CALL1:.*]] = call {{.*}} @objc_msgSend -// CHECK: %[[V10:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL1]]) +// CHECK-O2: %[[V10:.*]] = call {{.*}} @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-O0: %[[CALL1:.*]] = call {{.*}} @objc_msgSend +// CHECK-O0: %[[V10:.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* %[[CALL1]]) // CHECK: %[[V11:.*]] = call i8* @llvm.objc.retain(i8* %[[V10]]) // CHECK: store i8* %[[V11]], i8** %[[OS_LOG_ARG2]], align 8 // CHECK: %[[V12:.*]] = ptrtoint i8* %[[V11]] to i64 diff --git a/clang/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm b/clang/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm --- a/clang/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm +++ b/clang/test/CodeGenObjCXX/arc-forwarded-lambda-call.mm @@ -4,9 +4,9 @@ extern void test0_helper(id (^)(void)); test0_helper([=]() { return x; }); // CHECK-LABEL: define internal i8* @___Z5test0P11objc_object_block_invoke - // CHECK: [[T0:%.*]] = call i8* @"_ZZ5test0P11objc_objectENK3$_0clEv" - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) - // CHECK-NEXT: [[T2:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T1]]) + // CHECK: [[T0:%.*]] = call i8* @"_ZZ5test0P11objc_objectENK3$_0clEv"{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]]) + // CHECK-NEXT: [[T2:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T0]]) // CHECK-NEXT: ret i8* [[T2]] } @@ -27,9 +27,9 @@ extern void test1_helper(id (*)(void)); test1_helper([](){ return test1_rv; }); // CHECK-LABEL: define internal i8* @"_ZZ5test1vEN3$_18__invokeEv" - // CHECK: [[T0:%.*]] = call i8* @"_ZZ5test1vENK3$_1clEv" - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) - // CHECK-NEXT: [[T2:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T1]]) + // CHECK: [[T0:%.*]] = call i8* @"_ZZ5test1vENK3$_1clEv"{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T0]]) + // CHECK-NEXT: [[T2:%.*]] = tail call i8* @llvm.objc.autoreleaseReturnValue(i8* [[T0]]) // CHECK-NEXT: ret i8* [[T2]] } diff --git a/clang/test/CodeGenObjCXX/arc-globals.mm b/clang/test/CodeGenObjCXX/arc-globals.mm --- a/clang/test/CodeGenObjCXX/arc-globals.mm +++ b/clang/test/CodeGenObjCXX/arc-globals.mm @@ -6,15 +6,15 @@ id getObject(); // CHECK-LABEL: define internal void @__cxx_global_var_init -// CHECK: call i8* @_Z9getObjectv -// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue +// CHECK: call i8* @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use // CHECK-NEXT: {{store i8*.*@global_obj}} // CHECK-NEXT: ret void id global_obj = getObject(); // CHECK-LABEL: define internal void @__cxx_global_var_init -// CHECK: call i8* @_Z9getObjectv -// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue +// CHECK: call i8* @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use // CHECK-NEXT: {{store i8*.*@global_obj2}} // CHECK-NEXT: ret void id global_obj2 = getObject(); diff --git a/clang/test/CodeGenObjCXX/arc-references.mm b/clang/test/CodeGenObjCXX/arc-references.mm --- a/clang/test/CodeGenObjCXX/arc-references.mm +++ b/clang/test/CodeGenObjCXX/arc-references.mm @@ -9,13 +9,13 @@ // Lifetime extension for binding a reference to an rvalue // CHECK-LABEL: define{{.*}} void @_Z5test0v() void test0() { - // CHECK: call i8* @_Z9getObjectv - // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call i8* @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use( const __strong id &ref1 = getObject(); // CHECK: call void @_Z6calleev callee(); - // CHECK: call i8* @_Z9getObjectv - // CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: call i8* @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use( // CHECK-NEXT: call i8* @llvm.objc.autorelease const __autoreleasing id &ref2 = getObject(); // CHECK: call void @_Z6calleev @@ -84,8 +84,8 @@ } // CHECK-LABEL: define internal void @__cxx_global_var_init( -// CHECK: call i8* @_Z9getObjectv -// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue +// CHECK: call i8* @_Z9getObjectv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use( const __strong id &global_ref = getObject(); // Note: we intentionally don't release the object. diff --git a/clang/test/CodeGenObjCXX/arc.mm b/clang/test/CodeGenObjCXX/arc.mm --- a/clang/test/CodeGenObjCXX/arc.mm +++ b/clang/test/CodeGenObjCXX/arc.mm @@ -19,8 +19,8 @@ // TODO: this is sub-optimal, we should retain at the actual call site. // TODO: in the non-volatile case, we do not need to be reloading. - // CHECK: [[T0:%.*]] = call i8* @_Z12test0_helperv() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @_Z12test0_helperv() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8 // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]]) // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.retain(i8* [[T3]]) @@ -28,8 +28,8 @@ // CHECK-NEXT: call void @llvm.objc.release(i8* [[T1]]) id x = *wp = test0_helper(); - // CHECK: [[T0:%.*]] = call i8* @_Z12test0_helperv() - // CHECK-NEXT: [[T1:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T0]]) + // CHECK: [[T1:%.*]] = call i8* @_Z12test0_helperv() [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use(i8* [[T1]]) // CHECK-NEXT: [[T2:%.*]] = load i8**, i8*** {{%.*}}, align 8 // CHECK-NEXT: [[T3:%.*]] = call i8* @llvm.objc.storeWeak(i8** [[T2]], i8* [[T1]]) // CHECK-NEXT: [[T4:%.*]] = call i8* @llvm.objc.loadWeakRetained(i8** [[T2]]) @@ -163,25 +163,20 @@ // CHECK-LABEL: define{{.*}} void @_Z7test35b13Test35_HelperPS_ void test35b(Test35_Helper x0, Test35_Helper *x0p) { // CHECK: call void @llvm.lifetime.start - // CHECK: call i8* @_ZN13Test35_Helper11makeObject3Ev - // CHECK: call i8* @llvm.objc.retain + // CHECK: call i8* @_ZN13Test35_Helper11makeObject3Ev{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] id obj1 = Test35_Helper::makeObject3(); // CHECK: call void @llvm.lifetime.start - // CHECK: call i8* @_ZN13Test35_Helper11makeObject4Ev - // CHECK: call i8* @llvm.objc.retain + // CHECK: call i8* @_ZN13Test35_Helper11makeObject4Ev{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] id obj2 = x0.makeObject4(); // CHECK: call void @llvm.lifetime.start - // CHECK: call i8* @_ZN13Test35_Helper11makeObject4Ev - // CHECK: call i8* @llvm.objc.retain + // CHECK: call i8* @_ZN13Test35_Helper11makeObject4Ev{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] id obj3 = x0p->makeObject4(); id (Test35_Helper::*pmf)() = &Test35_Helper::makeObject4; // CHECK: call void @llvm.lifetime.start - // CHECK: call i8* % - // CHECK: call i8* @llvm.objc.retain + // CHECK: call i8* %{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] id obj4 = (x0.*pmf)(); // CHECK: call void @llvm.lifetime.start - // CHECK: call i8* % - // CHECK: call i8* @llvm.objc.retain + // CHECK: call i8* %{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] id obj5 = (x0p->*pmf)(); // CHECK: call void @llvm.objc.release @@ -222,26 +217,24 @@ extern template void test37(Test37 *a); template void test37(Test37 *a); // CHECK-LABEL: define weak_odr void @_Z6test37I6Test37EvPT_( -// CHECK: [[T0:%.*]] = call [[NSARRAY]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to [[NSARRAY]]* (i8*, i8*)*)( -// CHECK-NEXT: [[T1:%.*]] = bitcast [[NSARRAY]]* [[T0]] to i8* -// CHECK-NEXT: [[T2:%.*]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[T1]]) -// CHECK-NEXT: [[COLL:%.*]] = bitcast i8* [[T2]] to [[NSARRAY]]* +// CHECK: [[T2:%.*]] = call [[NSARRAY]]* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to [[NSARRAY]]* (i8*, i8*)*)({{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use({{.*}} [[T2]]) // Make sure it's not immediately released before starting the iteration. // CHECK-NEXT: load i8*, i8** @OBJC_SELECTOR_REFERENCES_ -// CHECK-NEXT: [[T0:%.*]] = bitcast [[NSARRAY]]* [[COLL]] to i8* +// CHECK-NEXT: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8* // CHECK-NEXT: @objc_msgSend // This bitcast is for the mutation check. -// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[COLL]] to i8* +// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8* // CHECK-NEXT: @objc_enumerationMutation // This bitcast is for the 'next' message send. -// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[COLL]] to i8* +// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8* // CHECK-NEXT: @objc_msgSend // This bitcast is for the final release. -// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[COLL]] to i8* +// CHECK: [[T0:%.*]] = bitcast [[NSARRAY]]* [[T2]] to i8* // CHECK-NEXT: call void @llvm.objc.release(i8* [[T0]]) template @@ -250,10 +243,8 @@ } // CHECK-LABEL: define weak_odr void @_Z12send_releaseIiEvv( -// CHECK: call %0* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend -// CHECK-NEXT: bitcast -// CHECK-NEXT: call i8* @llvm.objc.retainAutoreleasedReturnValue -// CHECK-NEXT: bitcast +// CHECK: call %0* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] +// CHECK-NEXT: call void (...) @llvm.objc.clang.arc.noop.use( // CHECK-NEXT: bitcast // CHECK-NEXT: call void @llvm.objc.release // CHECK-NEXT: ret void diff --git a/clang/test/CodeGenObjCXX/literals.mm b/clang/test/CodeGenObjCXX/literals.mm --- a/clang/test/CodeGenObjCXX/literals.mm +++ b/clang/test/CodeGenObjCXX/literals.mm @@ -28,22 +28,19 @@ // CHECK-NEXT: [[TMP_CAST:%.*]] = bitcast {{.*}} [[TMPX]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP_CAST]]) // CHECK-NEXT: call void @_ZN1XC1Ev({{.*}} [[TMPX]]) - // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv - // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT0]]) - // CHECK: store i8* [[RET0]], i8** [[ELEMENT0]] + // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK: store i8* [[OBJECT0]], i8** [[ELEMENT0]] // Initializing the second element // CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 1 // CHECK-NEXT: [[TMP_CAST:%.*]] = bitcast {{.*}} [[TMPY]] to i8* // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 1, i8* [[TMP_CAST]]) // CHECK-NEXT: invoke void @_ZN1YC1Ev({{.*}} [[TMPY]]) - // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv - // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT1]]) - // CHECK: store i8* [[RET1]], i8** [[ELEMENT1]] + // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK: store i8* [[OBJECT1]], i8** [[ELEMENT1]] // Build the array - // CHECK: {{invoke.*@objc_msgSend}} - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: {{invoke.*@objc_msgSend}}{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] id arr = @[ X(), Y() ]; // Destroy temporaries @@ -82,20 +79,17 @@ // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* [[PTR1]]) // CHECK: [[ELEMENT0:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 0 // CHECK: call void @_ZN1XC1Ev - // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv - // CHECK: [[RET0:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT0]]) - // CHECK: store i8* [[RET0]], i8** [[ELEMENT0]] + // CHECK-NEXT: [[OBJECT0:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1XcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK: store i8* [[OBJECT0]], i8** [[ELEMENT0]] // Initializing the second element // CHECK: [[ELEMENT1:%[a-zA-Z0-9.]+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[OBJECTS]], i64 0, i64 1 // CHECK: invoke void @_ZN1YC1Ev - // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv - // CHECK: [[RET1:%[a-zA-Z0-9.]+]] = notail call i8* @llvm.objc.retainAutoreleasedReturnValue(i8* [[OBJECT1]]) - // CHECK: store i8* [[RET1]], i8** [[ELEMENT1]] + // CHECK: [[OBJECT1:%[a-zA-Z0-9.]+]] = invoke i8* @_ZNK1YcvP11objc_objectEv{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] + // CHECK: store i8* [[OBJECT1]], i8** [[ELEMENT1]] // Build the array - // CHECK: {{invoke.*@objc_msgSend}} - // CHECK: call i8* @llvm.objc.retainAutoreleasedReturnValue + // CHECK: {{invoke.*@objc_msgSend}}{{.*}} [ "clang.arc.attachedcall"(i8* (i8*)* @llvm.objc.retainAutoreleasedReturnValue) ] id arr = @[ X(), Y() ]; // Destroy temporaries