mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
We deallocate an instruction's packs at points where no further control flow path uses the value. In the case of an alloc_stack, this will be right after the dealloc_stack. Thus, if alloc_stack allocates some packs to build type metadata for a tuple type that contains a pack, and then proceeds to allocate a value large enough to hold the tuple, we will free the second allocation first, before we free the pack, as expected. However, after stack allocating the value, alloc_stack does some further work to emit debug info. This could result in emission of additional metadata packs. Split up the debug info emission into two parts; the first we do before we perform the stack allocation, the rest we do after. - Fixes https://github.com/swiftlang/swift/issues/67702. - Fixes rdar://problem/141363236.
21 lines
768 B
Swift
21 lines
768 B
Swift
// RUN: %target-swift-frontend -emit-ir %s -target %target-swift-5.9-abi-triple | %FileCheck %s
|
|
|
|
protocol P {
|
|
associatedtype A
|
|
var a: A { get }
|
|
}
|
|
|
|
func f<each T: P>(_ t: repeat each T) -> (repeat (each T).A) {
|
|
let data = (repeat (each t).a)
|
|
return data
|
|
}
|
|
|
|
// CHECK-LABEL: define {{.*}} void @"$s21pack_metadata_dealloc1fy1AQzxQp_txxQpRvzAA1PRzlF"
|
|
// CHECK: [[SPSAVE:%.*]] = call ptr @llvm.stacksave.p0()
|
|
// CHECK: call void @llvm.stackrestore.p0(ptr [[SPSAVE]])
|
|
// CHECK: [[SPSAVE1:%.*]] = call ptr @llvm.stacksave.p0()
|
|
// CHECK: [[SPSAVE2:%.*]] = call ptr @llvm.stacksave.p0()
|
|
// CHECK-NOT: call ptr llvm.stacksave.p0()
|
|
// CHECK: call void @llvm.stackrestore.p0(ptr [[SPSAVE2]])
|
|
// CHECK: call void @llvm.stackrestore.p0(ptr [[SPSAVE1]])
|
|
// CHECK: ret void |