Skip to content

Commit 370a4ea

Browse files
committed
SILGen Builtin.loadRaw with alignment=1
This adds compiler support for misaligned raw pointer access. A Swift Evolution proposal is required before users can take advantage of this.
1 parent 056ebe3 commit 370a4ea

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed

lib/SILGen/SILGenBuiltin.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ static ManagedValue emitBuiltinLoadOrTake(SILGenFunction &SGF,
101101
SGFContext C,
102102
IsTake_t isTake,
103103
bool isStrict,
104-
bool isInvariant) {
104+
bool isInvariant,
105+
llvm::MaybeAlign align) {
105106
assert(substitutions.getReplacementTypes().size() == 1 &&
106107
"load should have single substitution");
107108
assert(args.size() == 1 && "load should have a single argument");
@@ -113,9 +114,12 @@ static ManagedValue emitBuiltinLoadOrTake(SILGenFunction &SGF,
113114
SILType loadedType = rvalueTL.getLoweredType();
114115

115116
// Convert the pointer argument to a SIL address.
117+
//
118+
// Default to an unaligned pointer. This can be optimized in the presence of
119+
// Builtin.assumeAlignment.
116120
SILValue addr = SGF.B.createPointerToAddress(loc, args[0].getUnmanagedValue(),
117121
loadedType.getAddressType(),
118-
isStrict, isInvariant);
122+
isStrict, isInvariant, align);
119123
// Perform the load.
120124
return SGF.emitLoad(loc, addr, rvalueTL, C, isTake);
121125
}
@@ -125,39 +129,47 @@ static ManagedValue emitBuiltinLoad(SILGenFunction &SGF,
125129
SubstitutionMap substitutions,
126130
ArrayRef<ManagedValue> args,
127131
SGFContext C) {
132+
// Regular loads assume natural alignment.
128133
return emitBuiltinLoadOrTake(SGF, loc, substitutions, args,
129134
C, IsNotTake,
130-
/*isStrict*/ true, /*isInvariant*/ false);
135+
/*isStrict*/ true, /*isInvariant*/ false,
136+
llvm::MaybeAlign());
131137
}
132138

133139
static ManagedValue emitBuiltinLoadRaw(SILGenFunction &SGF,
134140
SILLocation loc,
135141
SubstitutionMap substitutions,
136142
ArrayRef<ManagedValue> args,
137143
SGFContext C) {
144+
// Raw loads cannot assume alignment.
138145
return emitBuiltinLoadOrTake(SGF, loc, substitutions, args,
139146
C, IsNotTake,
140-
/*isStrict*/ false, /*isInvariant*/ false);
147+
/*isStrict*/ false, /*isInvariant*/ false,
148+
llvm::MaybeAlign(1));
141149
}
142150

143151
static ManagedValue emitBuiltinLoadInvariant(SILGenFunction &SGF,
144152
SILLocation loc,
145153
SubstitutionMap substitutions,
146154
ArrayRef<ManagedValue> args,
147155
SGFContext C) {
156+
// Regular loads assume natural alignment.
148157
return emitBuiltinLoadOrTake(SGF, loc, substitutions, args,
149158
C, IsNotTake,
150-
/*isStrict*/ false, /*isInvariant*/ true);
159+
/*isStrict*/ false, /*isInvariant*/ true,
160+
llvm::MaybeAlign());
151161
}
152162

153163
static ManagedValue emitBuiltinTake(SILGenFunction &SGF,
154164
SILLocation loc,
155165
SubstitutionMap substitutions,
156166
ArrayRef<ManagedValue> args,
157167
SGFContext C) {
168+
// Regular loads assume natural alignment.
158169
return emitBuiltinLoadOrTake(SGF, loc, substitutions, args,
159170
C, IsTake,
160-
/*isStrict*/ true, /*isInvariant*/ false);
171+
/*isStrict*/ true, /*isInvariant*/ false,
172+
llvm::MaybeAlign());
161173
}
162174

163175
/// Specialized emitter for Builtin.destroy.

test/IRGen/builtins.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func load_test(_ ptr: Builtin.RawPointer) -> Builtin.Int64 {
9797
// CHECK: define hidden {{.*}}i64 @"$s8builtins13load_raw_test{{[_0-9a-zA-Z]*}}F"
9898
func load_raw_test(_ ptr: Builtin.RawPointer) -> Builtin.Int64 {
9999
// CHECK: [[CASTPTR:%.*]] = bitcast i8* [[PTR:%.*]] to i64*
100-
// CHECK-NEXT: load i64, i64* [[CASTPTR]]
100+
// CHECK-NEXT: load i64, i64* [[CASTPTR]], align 1
101101
// CHECK: ret
102102
return Builtin.loadRaw(ptr)
103103
}
@@ -118,7 +118,7 @@ func load_object_test(_ ptr: Builtin.RawPointer) -> Builtin.NativeObject {
118118

119119
// CHECK: define hidden {{.*}}%swift.refcounted* @"$s8builtins20load_raw_object_test{{[_0-9a-zA-Z]*}}F"
120120
func load_raw_object_test(_ ptr: Builtin.RawPointer) -> Builtin.NativeObject {
121-
// CHECK: [[T0:%.*]] = load [[REFCOUNT]]*, [[REFCOUNT]]**
121+
// CHECK: [[T0:%.*]] = load [[REFCOUNT]]*, [[REFCOUNT]]** %{{.*}}, align 1
122122
// CHECK: call [[REFCOUNT]]* @swift_retain([[REFCOUNT]]* returned [[T0]])
123123
// CHECK: ret [[REFCOUNT]]* [[T0]]
124124
return Builtin.loadRaw(ptr)

test/SILGen/builtins.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ func load_obj(_ x: Builtin.RawPointer) -> Builtin.NativeObject {
3333

3434
// CHECK-LABEL: sil hidden [ossa] @$s8builtins12load_raw_pod{{[_0-9a-zA-Z]*}}F
3535
func load_raw_pod(_ x: Builtin.RawPointer) -> Builtin.Int64 {
36-
// CHECK: [[ADDR:%.*]] = pointer_to_address {{%.*}} to $*Builtin.Int64
36+
// CHECK: [[ADDR:%.*]] = pointer_to_address {{%.*}} to [align=1] $*Builtin.Int64
3737
// CHECK: [[VAL:%.*]] = load [trivial] [[ADDR]]
3838
// CHECK: return [[VAL]]
3939
return Builtin.loadRaw(x)
4040
}
4141

4242
// CHECK-LABEL: sil hidden [ossa] @$s8builtins12load_raw_obj{{[_0-9a-zA-Z]*}}F
4343
func load_raw_obj(_ x: Builtin.RawPointer) -> Builtin.NativeObject {
44-
// CHECK: [[ADDR:%.*]] = pointer_to_address {{%.*}} to $*Builtin.NativeObject
44+
// CHECK: [[ADDR:%.*]] = pointer_to_address {{%.*}} to [align=1] $*Builtin.NativeObject
4545
// CHECK: [[VAL:%.*]] = load [copy] [[ADDR]]
4646
// CHECK: return [[VAL]]
4747
return Builtin.loadRaw(x)

0 commit comments

Comments
 (0)