Skip to content

Commit 4858cb6

Browse files
committed
[IRGen][interop] do not add 'nocapture' to not bitwise takable types
The use of 'nocapture' for parameters and return values is incorrect for C++ types, as they can actually capture a pointer into its own value (e.g. std::string in libstdc++) rdar://115062687
1 parent 79cdadf commit 4858cb6

File tree

161 files changed

+396
-384
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

161 files changed

+396
-384
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,10 @@ static void addIndirectValueParameterAttributes(IRGenModule &IGM,
266266
llvm::AttrBuilder b(IGM.getLLVMContext());
267267
// Value parameter pointers can't alias or be captured.
268268
b.addAttribute(llvm::Attribute::NoAlias);
269-
b.addAttribute(llvm::Attribute::NoCapture);
269+
// Bitwise takable value types are guaranteed not to capture
270+
// a pointer into itself.
271+
if (ti.isBitwiseTakable(ResilienceExpansion::Maximal))
272+
b.addAttribute(llvm::Attribute::NoCapture);
270273
// The parameter must reference dereferenceable memory of the type.
271274
addDereferenceableAttributeToBuilder(IGM, b, ti);
272275

@@ -278,9 +281,11 @@ static void addPackParameterAttributes(IRGenModule &IGM,
278281
llvm::AttributeList &attrs,
279282
unsigned argIndex) {
280283
llvm::AttrBuilder b(IGM.getLLVMContext());
281-
// Pack parameter pointers can't alias or be captured.
284+
// Pack parameter pointers can't alias.
285+
// Note: they are not marked `nocapture` as one
286+
// pack parameter could be a value type (e.g. a C++ type)
287+
// that captures its own pointer in itself.
282288
b.addAttribute(llvm::Attribute::NoAlias);
283-
b.addAttribute(llvm::Attribute::NoCapture);
284289
// TODO: we could mark this dereferenceable when the pack has fixed
285290
// components.
286291
// TODO: add an alignment attribute
@@ -301,8 +306,10 @@ static void addInoutParameterAttributes(IRGenModule &IGM, SILType paramSILType,
301306
// attribute if it's a pointer being passed inout.
302307
b.addAttribute(llvm::Attribute::NoAlias);
303308
}
304-
// Aliasing inouts can't be captured without doing unsafe stuff.
305-
b.addAttribute(llvm::Attribute::NoCapture);
309+
// Bitwise takable value types are guaranteed not to capture
310+
// a pointer into itself.
311+
if (ti.isBitwiseTakable(ResilienceExpansion::Maximal))
312+
b.addAttribute(llvm::Attribute::NoCapture);
306313
// The inout must reference dereferenceable memory of the type.
307314
addDereferenceableAttributeToBuilder(IGM, b, ti);
308315

@@ -341,10 +348,14 @@ llvm::CallingConv::ID irgen::expandCallingConv(IRGenModule &IGM,
341348
static void addIndirectResultAttributes(IRGenModule &IGM,
342349
llvm::AttributeList &attrs,
343350
unsigned paramIndex, bool allowSRet,
344-
llvm::Type *storageType) {
351+
llvm::Type *storageType,
352+
const TypeInfo &typeInfo) {
345353
llvm::AttrBuilder b(IGM.getLLVMContext());
346354
b.addAttribute(llvm::Attribute::NoAlias);
347-
b.addAttribute(llvm::Attribute::NoCapture);
355+
// Bitwise takable value types are guaranteed not to capture
356+
// a pointer into itself.
357+
if (typeInfo.isBitwiseTakable(ResilienceExpansion::Maximal))
358+
b.addAttribute(llvm::Attribute::NoCapture);
348359
if (allowSRet) {
349360
assert(storageType);
350361
b.addStructRetAttr(storageType);
@@ -509,7 +520,7 @@ llvm::Type *SignatureExpansion::addIndirectResult() {
509520
const TypeInfo &resultTI = IGM.getTypeInfo(resultType);
510521
auto storageTy = resultTI.getStorageType();
511522
addIndirectResultAttributes(IGM, Attrs, ParamIRTypes.size(), claimSRet(),
512-
storageTy);
523+
storageTy, resultTI);
513524
addPointerParameter(storageTy);
514525
return IGM.VoidTy;
515526
}
@@ -568,11 +579,12 @@ void SignatureExpansion::expandIndirectResults() {
568579
auto useSRet = claimSRet();
569580
// We need to use opaque types or non fixed size storage types because llvm
570581
// does type based analysis based on the type of sret arguments.
571-
if (useSRet && !isa<FixedTypeInfo>(IGM.getTypeInfo(indirectResultType))) {
582+
const TypeInfo &typeInfo = IGM.getTypeInfo(indirectResultType);
583+
if (useSRet && !isa<FixedTypeInfo>(typeInfo)) {
572584
storageTy = IGM.OpaqueTy;
573585
}
574586
addIndirectResultAttributes(IGM, Attrs, ParamIRTypes.size(), useSRet,
575-
storageTy);
587+
storageTy, typeInfo);
576588
addPointerParameter(storageTy);
577589
}
578590
}
@@ -1459,7 +1471,7 @@ void SignatureExpansion::expandExternalSignatureTypes() {
14591471
param, IGM.getMaximalTypeExpansionContext());
14601472
auto &paramTI = cast<FixedTypeInfo>(IGM.getTypeInfo(paramTy));
14611473
addIndirectResultAttributes(IGM, Attrs, getCurParamIndex(), claimSRet(),
1462-
paramTI.getStorageType());
1474+
paramTI.getStorageType(), paramTI);
14631475
break;
14641476
}
14651477
}

test/AutoDiff/IRGen/runtime.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ func test_context_builtins_with_type<T>(t: T) {
1212
UnsafeMutableRawPointer(newBuffer).storeBytes(of: t, as: T.self)
1313
}
1414

15-
// CHECK-LABEL: define{{.*}}@test_context_builtins_with_type(ptr noalias nocapture %0, ptr %T)
15+
// CHECK-LABEL: define{{.*}}@test_context_builtins_with_type(ptr noalias %0, ptr %T)
1616
// CHECK: entry:
1717
// CHECK: [[CTX:%.*]] = call swiftcc ptr @swift_autoDiffCreateLinearMapContextWithType(ptr %T)
1818
// CHECK: call swiftcc ptr @swift_autoDiffProjectTopLevelSubcontext(ptr [[CTX]])

test/DebugInfo/inlined-generics-basic.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public class C<R> {
4444

4545
// SIL-LABEL: // C.f<A>(_:)
4646
// IR-LABEL: define {{.*}} @"$s1A1CC1fyyqd__lF"
47-
// IR-SAME: nocapture %[[ARG_0:.*]], {{.*}} %[[ARG_S:.*]],
47+
// IR-SAME: %[[ARG_0:.*]], {{.*}} %[[ARG_S:.*]],
4848
#sourceLocation(file: "f.swift", line: 1)
4949
public func f<S>(_ s: S) {
5050
// SIL: debug_value %0 : $*S, let, name "s", argno 1, expr op_deref, {{.*}} scope [[F]]

test/DebugInfo/move_function_dbginfo.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ public func copyableVarArgTest(_ k: inout Klass) {
218218
k.doSomething()
219219
}
220220

221-
// CHECK-LABEL: define swiftcc void @"$s21move_function_dbginfo20addressOnlyValueTestyyxAA1PRzlF"(ptr noalias nocapture %0, ptr %T, ptr %T.P)
221+
// CHECK-LABEL: define swiftcc void @"$s21move_function_dbginfo20addressOnlyValueTestyyxAA1PRzlF"(ptr noalias %0, ptr %T, ptr %T.P)
222222
// CHECK: @llvm.dbg.addr(metadata ptr %{{.*}}, metadata ![[K_ADDR_LET_METADATA:[0-9]+]], metadata !DIExpression()), !dbg ![[ADDR_LOC:[0-9]*]]
223223
// CHECK-NEXT: br
224224
// CHECK: @llvm.dbg.value(metadata ptr undef, metadata ![[K_ADDR_LET_METADATA]], metadata !DIExpression()), !dbg ![[ADDR_LOC]]
@@ -308,7 +308,7 @@ public func addressOnlyValueArgTest<T : P>(_ k: __owned T) {
308308
m.doSomething()
309309
}
310310

311-
// CHECK-LABEL: define swiftcc void @"$s21move_function_dbginfo18addressOnlyVarTestyyxAA1PRzlF"(ptr noalias nocapture %0, ptr %T, ptr %T.P)
311+
// CHECK-LABEL: define swiftcc void @"$s21move_function_dbginfo18addressOnlyVarTestyyxAA1PRzlF"(ptr noalias %0, ptr %T, ptr %T.P)
312312
// CHECK: @llvm.dbg.addr(metadata ptr %{{.*}}, metadata ![[K_ADDRONLY_VAR_METADATA:[0-9]+]], metadata !DIExpression()), !dbg ![[ADDR_LOC:[0-9]*]]
313313
// CHECK-NEXT: br
314314
// CHECK: @llvm.dbg.value(metadata ptr undef, metadata ![[K_ADDRONLY_VAR_METADATA]], metadata !DIExpression()), !dbg ![[ADDR_LOC]]

test/DebugInfo/struct_resilience.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
//
1212
import resilient_struct
1313

14-
// CHECK-LABEL: define{{.*}} swiftcc void @"$s17struct_resilience9takesSizeyy010resilient_A00D0VF"(ptr noalias nocapture %0)
15-
// CHECK-LLDB-LABEL: define{{.*}} swiftcc void @"$s17struct_resilience9takesSizeyy010resilient_A00D0VF"(ptr noalias nocapture dereferenceable({{8|16}}) %0)
14+
// CHECK-LABEL: define{{.*}} swiftcc void @"$s17struct_resilience9takesSizeyy010resilient_A00D0VF"(ptr noalias %0)
15+
// CHECK-LLDB-LABEL: define{{.*}} swiftcc void @"$s17struct_resilience9takesSizeyy010resilient_A00D0VF"(ptr noalias dereferenceable({{8|16}}) %0)
1616
public func takesSize(_ s: Size) {}
1717

1818

test/Distributed/distributed_actor_accessor_thunks_64bit.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public distributed actor MyOtherActor {
9494

9595
// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTE"
9696

97-
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTETF"(ptr swiftasync %0, ptr nocapture %1, ptr %2, ptr %3, {{.*}}, ptr [[ACTOR:%.*]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
97+
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTETF"(ptr swiftasync %0, ptr %1, ptr %2, ptr %3, {{.*}}, ptr [[ACTOR:%.*]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
9898

9999
/// Read the current offset and cast an element to `Int`
100100

@@ -116,7 +116,7 @@ public distributed actor MyOtherActor {
116116
// CHECK: missing-witness1:
117117
// CHECK-NEXT: call void @llvm.trap()
118118
// CHECK-NEXT: unreachable
119-
// CHECK: call swiftcc void @"$s27FakeDistributedActorSystems0A17InvocationDecoderC18decodeNextArgumentxyKSeRzSERzlF"(ptr noalias nocapture sret(%swift.opaque) [[ARG_0_VALUE_BUF]], ptr %arg_type, ptr [[ENCODABLE_WITNESS]], ptr [[DECODABLE_WITNESS]], ptr swiftself [[DECODER]], ptr noalias nocapture swifterror dereferenceable(8) %swifterror)
119+
// CHECK: call swiftcc void @"$s27FakeDistributedActorSystems0A17InvocationDecoderC18decodeNextArgumentxyKSeRzSERzlF"(ptr noalias sret(%swift.opaque) [[ARG_0_VALUE_BUF]], ptr %arg_type, ptr [[ENCODABLE_WITNESS]], ptr [[DECODABLE_WITNESS]], ptr swiftself [[DECODER]], ptr noalias nocapture swifterror dereferenceable(8) %swifterror)
120120

121121
// CHECK: store ptr null, ptr %swifterror
122122
// CHECK-NEXT: %._value = getelementptr inbounds %TSi, ptr [[ARG_0_VALUE_BUF]], i32 0, i32 0
@@ -192,7 +192,7 @@ public distributed actor MyOtherActor {
192192
// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTE"
193193

194194
/// !!! in `simple3` interesting bits are: argument value extraction (because string is exploded into N arguments) and call to distributed thunk
195-
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTETF"(ptr swiftasync %0, ptr nocapture [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUFF:%.*]], ptr [[SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr [[ACTOR]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
195+
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTETF"(ptr swiftasync %0, ptr [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUFF:%.*]], ptr [[SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr [[ACTOR]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
196196

197197

198198
// CHECK: [[ARG_SIZE:%.*]] = and i64 {{.*}}, -16
@@ -232,7 +232,7 @@ public distributed actor MyOtherActor {
232232

233233
// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTE"
234234

235-
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTETF"(ptr swiftasync %0, ptr nocapture [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUFF:%.*]], ptr [[SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr [[ACTOR]], ptr [[DECODER_TYPE]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
235+
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTETF"(ptr swiftasync %0, ptr [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUFF:%.*]], ptr [[SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr [[ACTOR]], ptr [[DECODER_TYPE]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
236236

237237
/// Let's check that the call doesn't have any arguments and returns nothing.
238238

@@ -272,7 +272,7 @@ public distributed actor MyOtherActor {
272272

273273
// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTE"
274274

275-
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTETF"(ptr swiftasync {{.*}}, ptr nocapture [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUFF:%.*]], ptr [[SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr [[ACTOR]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
275+
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTETF"(ptr swiftasync {{.*}}, ptr [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUFF:%.*]], ptr [[SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr [[ACTOR]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
276276

277277
/// First, let's check that all of the different argument types here are loaded correctly.
278278

@@ -319,7 +319,7 @@ public distributed actor MyOtherActor {
319319

320320
/// ---> Accessor for `genericArgs`
321321

322-
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC11genericArgsyyx_Sayq_GtYaKSeRzSERzSeR_SER_r0_lFTETF"(ptr swiftasync %0, ptr nocapture [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUF:%.*]], ptr [[GENERIC_SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr [[ACTOR:%.*]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
322+
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC11genericArgsyyx_Sayq_GtYaKSeRzSERzSeR_SER_r0_lFTETF"(ptr swiftasync %0, ptr [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUF:%.*]], ptr [[GENERIC_SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr [[ACTOR:%.*]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
323323

324324
/// ---> Load `T`
325325

@@ -368,7 +368,7 @@ public distributed actor MyOtherActor {
368368

369369
/// Let's check that there is argument decoding since parameter list is empty
370370

371-
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTETF"(ptr swiftasync {{.*}}, ptr nocapture [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUFF:%.*]], ptr [[SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr {{.*}}, ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
371+
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTETF"(ptr swiftasync {{.*}}, ptr [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUFF:%.*]], ptr [[SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr {{.*}}, ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
372372
// CHECK-NEXT: entry:
373373
// CHECK-NEXT: {{.*}} = alloca ptr
374374
// CHECK-NEXT: %swifterror = alloca swifterror ptr

test/IRGen/TestABIInaccessible.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public struct AnotherType<T> {
88
}
99

1010
// Don't pass the metadata of Private<T> to AnotherType<T>'s outlined destroy.
11-
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s4main4copyyAA11AnotherTypeVyxGAElF"(ptr noalias nocapture sret({{.*}}) %0, ptr noalias nocapture %1, ptr %T)
11+
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @"$s4main4copyyAA11AnotherTypeVyxGAElF"(ptr noalias sret({{.*}}) %0, ptr noalias %1, ptr %T)
1212
// CHECK: [[MD:%.*]] = call swiftcc %swift.metadata_response @"$s4main11AnotherTypeVMa"(i{{.*}} 0, ptr %T)
1313
// CHECK: [[MD1:%.*]] = extractvalue %swift.metadata_response [[MD]], 0
1414
// CHECK: [[MD2:%.*]] = call swiftcc %swift.metadata_response @"$s4main6PublicVMa"(i{{.*}} 0, ptr %T)

test/IRGen/archetype_resilience.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public enum EnumWithClassArchetypeAndDynamicSize<T : AnyObject> {
1616
case B(Size)
1717
}
1818

19-
// CHECK-LABEL: define swiftcc void @copyDynamicMultiEnum(ptr %"EnumWithClassArchetypeAndDynamicSize<T>", ptr %U, ptr noalias nocapture swiftself %0)
19+
// CHECK-LABEL: define swiftcc void @copyDynamicMultiEnum(ptr %"EnumWithClassArchetypeAndDynamicSize<T>", ptr %U, ptr noalias swiftself %0)
2020
// CHECK: call ptr @"$s20archetype_resilience36EnumWithClassArchetypeAndDynamicSizeOyxGRlzCr0_lWOc"(ptr %0, ptr {{.*}}, ptr %"EnumWithClassArchetypeAndDynamicSize<T>")
2121
// CHECK: ret void
2222
sil [ossa] @copyDynamicMultiEnum : $@convention(method) <T, U where T: AnyObject> (@in_guaranteed EnumWithClassArchetypeAndDynamicSize<T>) -> () {

0 commit comments

Comments
 (0)