mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
SILGen: Don't copy_addr [take] trivial address-only values.
This is a new case that comes up with `InlineArray`, since an `InlineArray` with unknown count but known trivial element type is trivial but still address-only due to its unknown size. We are inconsistent about whether we emit formal copies or not of these values; they should generally be unnecessary as long as the memory location of a value is sufficiently long-lived, but the SIL verifier still reasonably considers a `[take]` as an invalidation of the memory, even though at runtime a take is a no-op. Since the take is unnecessary, we can just not take when we copy out of a trivial address location. Fixes #84141 | rdar://160007939.
This commit is contained in:
@@ -5234,7 +5234,9 @@ void SILGenFunction::emitSemanticStore(SILLocation loc,
|
||||
assert(!silConv.useLoweredAddresses() ||
|
||||
(dest->getType().isAddressOnly(F) == rvalue->getType().isAddress()));
|
||||
if (rvalue->getType().isAddress()) {
|
||||
B.createCopyAddr(loc, rvalue, dest, IsTake, isInit);
|
||||
B.createCopyAddr(loc, rvalue, dest,
|
||||
rvalue->getType().isTrivial(F) ? IsNotTake : IsTake,
|
||||
isInit);
|
||||
} else {
|
||||
emitUnloweredStoreOfCopy(B, loc, rvalue, dest, isInit);
|
||||
}
|
||||
|
||||
15
test/SILGen/trivial_address_only_switch.swift
Normal file
15
test/SILGen/trivial_address_only_switch.swift
Normal file
@@ -0,0 +1,15 @@
|
||||
// RUN: %target-swift-emit-silgen -verify -disable-availability-checking %s
|
||||
|
||||
public enum StreamYieldResult<let count: Int>: Sendable {
|
||||
case literal(buffer: InlineArray<count, UInt8>)
|
||||
case end(buffer: InlineArray<count, UInt8>, endIndex: Int)
|
||||
|
||||
public func buffer() -> InlineArray<count, UInt8> {
|
||||
switch self {
|
||||
case .literal(let b):
|
||||
return b
|
||||
case .end(let b, _):
|
||||
return b
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,7 @@ public struct Container<each T> {
|
||||
// Finally, the actual assignment.
|
||||
// CHECK-NEXT: [[ACCESS:%.*]] = begin_access [modify] [unknown] %1 :
|
||||
// CHECK-NEXT: [[FIELD:%.*]] = struct_element_addr [[ACCESS]] : $*Container<repeat each T>, #Container.storage
|
||||
// CHECK-NEXT: copy_addr [take] [[COPY2]] to [[FIELD]] : $*(repeat Stored<each T>)
|
||||
// CHECK-NEXT: copy_addr [[COPY2]] to [[FIELD]] : $*(repeat Stored<each T>)
|
||||
// CHECK-NEXT: end_access [[ACCESS]]
|
||||
// Clean up.
|
||||
// CHECK-NEXT: dealloc_stack [[COPY2]]
|
||||
|
||||
Reference in New Issue
Block a user