@@ -265,14 +265,19 @@ static void addIndirectValueParameterAttributes(IRGenModule &IGM,
265
265
attrs = attrs.addParamAttributes (IGM.getLLVMContext (), argIndex, b);
266
266
}
267
267
268
- static void addInoutParameterAttributes (IRGenModule &IGM,
268
+ static void addInoutParameterAttributes (IRGenModule &IGM, SILType paramSILType,
269
269
llvm::AttributeList &attrs,
270
270
const TypeInfo &ti, unsigned argIndex,
271
271
bool aliasable) {
272
272
llvm::AttrBuilder b;
273
- // Aliasing inouts is unspecified, but we still want aliasing to be memory-
274
- // safe, so we can't mark inouts as noalias at the LLVM level.
275
- // They still can't be captured without doing unsafe stuff, though.
273
+ // Thanks to exclusivity checking, it is not possible to alias inouts except
274
+ // those that are inout_aliasable.
275
+ if (!aliasable && paramSILType.getASTType ()->getAnyPointerElementType ()) {
276
+ // To ward against issues with LLVM's alias analysis, for now, only add the
277
+ // attribute if it's a pointer being passed inout.
278
+ b.addAttribute (llvm::Attribute::NoAlias);
279
+ }
280
+ // Aliasing inouts can't be captured without doing unsafe stuff.
276
281
b.addAttribute (llvm::Attribute::NoCapture);
277
282
// The inout must reference dereferenceable memory of the type.
278
283
addDereferenceableAttributeToBuilder (IGM, b, ti);
@@ -1510,8 +1515,9 @@ void SignatureExpansion::expand(SILParameterInfo param) {
1510
1515
1511
1516
case ParameterConvention::Indirect_Inout:
1512
1517
case ParameterConvention::Indirect_InoutAliasable:
1513
- addInoutParameterAttributes (IGM, Attrs, ti, ParamIRTypes.size (),
1514
- conv == ParameterConvention::Indirect_InoutAliasable);
1518
+ addInoutParameterAttributes (
1519
+ IGM, paramSILType, Attrs, ti, ParamIRTypes.size (),
1520
+ conv == ParameterConvention::Indirect_InoutAliasable);
1515
1521
addPointerParameter (IGM.getStorageType (getSILFuncConventions ().getSILType (
1516
1522
param, IGM.getMaximalTypeExpansionContext ())));
1517
1523
return ;
0 commit comments