Skip to content

Commit 2b9a7c7

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

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
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.

test/stdlib/UnsafeRawPointer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ UnsafeMutableRawPointerExtraTestSuite.test("load.unaligned.SIMD")
134134

135135
offset = 11
136136
let vector32 = bytes.withUnsafeMutableBytes { buffer -> SIMD32<UInt8> in
137-
let aligned = buffer.baseAddress!.alignedUp(for: SIMD16<UInt8>.self)
137+
let aligned = buffer.baseAddress!.alignedUp(for: SIMD32<UInt8>.self)
138138
offset += buffer.baseAddress!.distance(to: aligned)
139139
return buffer.loadUnaligned(fromByteOffset: offset, as: SIMD32<UInt8>.self)
140140
}

0 commit comments

Comments
 (0)