Skip to content

Commit b5cc412

Browse files
committed
[stdlib] fix unaligned loads of 16-byte (and up) SIMD types
- this is a temporary workaround
1 parent 1b78a1f commit b5cc412

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

stdlib/public/core/UnsafeRawPointer.swift

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,13 +455,25 @@ public struct UnsafeRawPointer: _Pointer {
455455
/// - Returns: A new instance of type `T`, read from the raw bytes at
456456
/// `offset`. The returned instance isn't associated
457457
/// with the value in the range of memory referenced by this pointer.
458+
@inlinable
458459
@_alwaysEmitIntoClient
459460
public func loadUnaligned<T>(
460461
fromByteOffset offset: Int = 0,
461462
as type: T.Type
462463
) -> T {
463464
_debugPrecondition(_isPOD(T.self))
464-
return Builtin.loadRaw((self + offset)._rawValue)
465+
return withUnsafeTemporaryAllocation(of: T.self, capacity: 1) {
466+
let temporary = $0.baseAddress._unsafelyUnwrappedUnchecked
467+
Builtin.int_memcpy_RawPointer_RawPointer_Int64(
468+
temporary._rawValue,
469+
(self + offset)._rawValue,
470+
UInt64(MemoryLayout<T>.size)._value,
471+
/*volatile:*/ false._value
472+
)
473+
return temporary.pointee
474+
}
475+
//FIXME: reimplement with `loadRaw` when supported in SIL (rdar://96956089)
476+
// e.g. Builtin.loadRaw((self + offset)._rawValue)
465477
}
466478
}
467479

@@ -1180,13 +1192,25 @@ public struct UnsafeMutableRawPointer: _Pointer {
11801192
/// - Returns: A new instance of type `T`, read from the raw bytes at
11811193
/// `offset`. The returned instance isn't associated
11821194
/// with the value in the range of memory referenced by this pointer.
1195+
@inlinable
11831196
@_alwaysEmitIntoClient
11841197
public func loadUnaligned<T>(
11851198
fromByteOffset offset: Int = 0,
11861199
as type: T.Type
11871200
) -> T {
11881201
_debugPrecondition(_isPOD(T.self))
1189-
return Builtin.loadRaw((self + offset)._rawValue)
1202+
return withUnsafeTemporaryAllocation(of: T.self, capacity: 1) {
1203+
let temporary = $0.baseAddress._unsafelyUnwrappedUnchecked
1204+
Builtin.int_memcpy_RawPointer_RawPointer_Int64(
1205+
temporary._rawValue,
1206+
(self + offset)._rawValue,
1207+
UInt64(MemoryLayout<T>.size)._value,
1208+
/*volatile:*/ false._value
1209+
)
1210+
return temporary.pointee
1211+
}
1212+
//FIXME: reimplement with `loadRaw` when supported in SIL (rdar://96956089)
1213+
// e.g. Builtin.loadRaw((self + offset)._rawValue)
11901214
}
11911215

11921216
/// Stores the given value's bytes into raw memory at the specified offset.

0 commit comments

Comments
 (0)