@@ -266,7 +266,8 @@ static void addIndirectValueParameterAttributes(IRGenModule &IGM,
266
266
llvm::AttrBuilder b (IGM.getLLVMContext ());
267
267
// Value parameter pointers can't alias or be captured.
268
268
b.addAttribute (llvm::Attribute::NoAlias);
269
- b.addAttribute (llvm::Attribute::NoCapture);
269
+ if (ti.isBitwiseTakable (ResilienceExpansion::Maximal))
270
+ b.addAttribute (llvm::Attribute::NoCapture);
270
271
// The parameter must reference dereferenceable memory of the type.
271
272
addDereferenceableAttributeToBuilder (IGM, b, ti);
272
273
@@ -278,9 +279,11 @@ static void addPackParameterAttributes(IRGenModule &IGM,
278
279
llvm::AttributeList &attrs,
279
280
unsigned argIndex) {
280
281
llvm::AttrBuilder b (IGM.getLLVMContext ());
281
- // Pack parameter pointers can't alias or be captured.
282
+ // Pack parameter pointers can't alias.
283
+ // Note: they are not marked `nocapture` as one
284
+ // pack parameter could be a value type (e.g. a C++ type)
285
+ // that captures its own pointer in itself.
282
286
b.addAttribute (llvm::Attribute::NoAlias);
283
- b.addAttribute (llvm::Attribute::NoCapture);
284
287
// TODO: we could mark this dereferenceable when the pack has fixed
285
288
// components.
286
289
// TODO: add an alignment attribute
@@ -302,7 +305,8 @@ static void addInoutParameterAttributes(IRGenModule &IGM, SILType paramSILType,
302
305
b.addAttribute (llvm::Attribute::NoAlias);
303
306
}
304
307
// Aliasing inouts can't be captured without doing unsafe stuff.
305
- b.addAttribute (llvm::Attribute::NoCapture);
308
+ if (ti.isBitwiseTakable (ResilienceExpansion::Maximal))
309
+ b.addAttribute (llvm::Attribute::NoCapture);
306
310
// The inout must reference dereferenceable memory of the type.
307
311
addDereferenceableAttributeToBuilder (IGM, b, ti);
308
312
@@ -341,10 +345,12 @@ llvm::CallingConv::ID irgen::expandCallingConv(IRGenModule &IGM,
341
345
static void addIndirectResultAttributes (IRGenModule &IGM,
342
346
llvm::AttributeList &attrs,
343
347
unsigned paramIndex, bool allowSRet,
344
- llvm::Type *storageType) {
348
+ llvm::Type *storageType,
349
+ const TypeInfo &typeInfo) {
345
350
llvm::AttrBuilder b (IGM.getLLVMContext ());
346
351
b.addAttribute (llvm::Attribute::NoAlias);
347
- b.addAttribute (llvm::Attribute::NoCapture);
352
+ if (typeInfo.isBitwiseTakable (ResilienceExpansion::Maximal))
353
+ b.addAttribute (llvm::Attribute::NoCapture);
348
354
if (allowSRet) {
349
355
assert (storageType);
350
356
b.addStructRetAttr (storageType);
@@ -509,7 +515,7 @@ llvm::Type *SignatureExpansion::addIndirectResult() {
509
515
const TypeInfo &resultTI = IGM.getTypeInfo (resultType);
510
516
auto storageTy = resultTI.getStorageType ();
511
517
addIndirectResultAttributes (IGM, Attrs, ParamIRTypes.size (), claimSRet (),
512
- storageTy);
518
+ storageTy, resultTI );
513
519
addPointerParameter (storageTy);
514
520
return IGM.VoidTy ;
515
521
}
@@ -568,11 +574,12 @@ void SignatureExpansion::expandIndirectResults() {
568
574
auto useSRet = claimSRet ();
569
575
// We need to use opaque types or non fixed size storage types because llvm
570
576
// does type based analysis based on the type of sret arguments.
571
- if (useSRet && !isa<FixedTypeInfo>(IGM.getTypeInfo (indirectResultType))) {
577
+ const TypeInfo &typeInfo = IGM.getTypeInfo (indirectResultType);
578
+ if (useSRet && !isa<FixedTypeInfo>(typeInfo)) {
572
579
storageTy = IGM.OpaqueTy ;
573
580
}
574
581
addIndirectResultAttributes (IGM, Attrs, ParamIRTypes.size (), useSRet,
575
- storageTy);
582
+ storageTy, typeInfo );
576
583
addPointerParameter (storageTy);
577
584
}
578
585
}
@@ -1459,7 +1466,7 @@ void SignatureExpansion::expandExternalSignatureTypes() {
1459
1466
param, IGM.getMaximalTypeExpansionContext ());
1460
1467
auto ¶mTI = cast<FixedTypeInfo>(IGM.getTypeInfo (paramTy));
1461
1468
addIndirectResultAttributes (IGM, Attrs, getCurParamIndex (), claimSRet (),
1462
- paramTI.getStorageType ());
1469
+ paramTI.getStorageType (), paramTI );
1463
1470
break ;
1464
1471
}
1465
1472
}
0 commit comments