Skip to content

Commit f045f14

Browse files
Merge pull request #42503 from nate-chandler/rdar76540030
[IRGen] Mark inout ptrs noalias.
2 parents c05e064 + d70d391 commit f045f14

File tree

3 files changed

+27
-6
lines changed

3 files changed

+27
-6
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -265,14 +265,19 @@ static void addIndirectValueParameterAttributes(IRGenModule &IGM,
265265
attrs = attrs.addParamAttributes(IGM.getLLVMContext(), argIndex, b);
266266
}
267267

268-
static void addInoutParameterAttributes(IRGenModule &IGM,
268+
static void addInoutParameterAttributes(IRGenModule &IGM, SILType paramSILType,
269269
llvm::AttributeList &attrs,
270270
const TypeInfo &ti, unsigned argIndex,
271271
bool aliasable) {
272272
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.
276281
b.addAttribute(llvm::Attribute::NoCapture);
277282
// The inout must reference dereferenceable memory of the type.
278283
addDereferenceableAttributeToBuilder(IGM, b, ti);
@@ -1510,8 +1515,9 @@ void SignatureExpansion::expand(SILParameterInfo param) {
15101515

15111516
case ParameterConvention::Indirect_Inout:
15121517
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);
15151521
addPointerParameter(IGM.getStorageType(getSILFuncConventions().getSILType(
15161522
param, IGM.getMaximalTypeExpansionContext())));
15171523
return;

test/IRGen/inout_noalias.sil

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %target-swift-frontend -parse-sil %s -emit-ir | %FileCheck %s
2+
3+
import Swift
4+
5+
// CHECK: define{{.*}}swiftcc void @takeInoutAliasable(%TSP* nocapture dereferenceable({{[0-9]+}}) %0, %swift.type* %T)
6+
sil @takeInoutAliasable : $<T> (@inout_aliasable UnsafePointer<T>) -> () {
7+
entry(%ptr : $*UnsafePointer<T>):
8+
%retval = tuple ()
9+
return %retval : $()
10+
}

test/IRGen/inout_noalias.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// RUN: %target-swift-frontend %s -emit-ir | %FileCheck %s
2+
3+
// CHECK: define{{.*}}swiftcc void @swapPointers({{.*}}noalias{{.*}},{{.*}}noalias{{.*}})
4+
@_silgen_name("swapPointers")
5+
public func swapPointers<T>(_ lhs: inout UnsafePointer<T>, _ rhs: inout UnsafePointer<T>) {}

0 commit comments

Comments
 (0)