Skip to content

Commit 56c8eba

Browse files
committed
[SIL] Fix alloc_stack [dynamic_lifetime] attribute cloning.
Make `SILCloner:visitAllocStack` correctly propagate the `[dynamic_lifetime]` attribute. Resolves SR-12886: differentiation transform error related to the `VJPEmitter` subclass of `SILCloner`.
1 parent c63153d commit 56c8eba

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-3
lines changed

include/swift/SIL/SILCloner.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -802,9 +802,9 @@ SILCloner<ImplClass>::visitAllocStackInst(AllocStackInst *Inst) {
802802
Loc = MandatoryInlinedLocation::getAutoGeneratedLocation();
803803
VarInfo = None;
804804
}
805-
recordClonedInstruction(Inst,
806-
getBuilder().createAllocStack(
807-
Loc, getOpType(Inst->getElementType()), VarInfo));
805+
recordClonedInstruction(Inst, getBuilder().createAllocStack(
806+
Loc, getOpType(Inst->getElementType()),
807+
VarInfo, Inst->hasDynamicLifetime()));
808808
}
809809

810810
template<typename ImplClass>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// RUN: %target-build-swift %s
2+
// RUN: %target-swift-frontend -emit-sil %s | %FileCheck %s
3+
4+
// SR-12493: SIL memory lifetime verification error due to
5+
// `SILCloner::visitAllocStack` not copying the `[dynamic_lifetime]` attribute.
6+
7+
import _Differentiation
8+
9+
enum Enum {
10+
case a
11+
}
12+
13+
struct Tensor<T>: Differentiable {
14+
@noDerivative var x: T
15+
@noDerivative var optional: Int?
16+
17+
init(_ x: T, _ e: Enum) {
18+
self.x = x
19+
switch e {
20+
case .a: optional = 1
21+
}
22+
}
23+
24+
// Definite initialization triggers for this initializer.
25+
@differentiable
26+
init(_ x: T, _ other: Self) {
27+
self = Self(x, Enum.a)
28+
}
29+
}
30+
31+
// Check that `allock_stack [dynamic_lifetime]` attribute is correctly cloned.
32+
33+
// CHECK-LABEL: sil hidden @$s4main6TensorVyACyxGx_ADtcfC : $@convention(method) <T> (@in T, @in Tensor<T>, @thin Tensor<T>.Type) -> @out Tensor<T> {
34+
// CHECK: [[SELF_ALLOC:%.*]] = alloc_stack [dynamic_lifetime] $Tensor<T>, var, name "self"
35+
36+
// CHECK-LABEL: sil hidden @AD__$s4main6TensorVyACyxGx_ADtcfC__vjp_src_0_wrt_1_l : $@convention(method) <τ_0_0> (@in τ_0_0, @in Tensor<τ_0_0>, @thin Tensor<τ_0_0>.Type) -> (@out Tensor<τ_0_0>, @owned @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0) -> @out τ_0_1 for <Tensor<τ_0_0>.TangentVector, Tensor<τ_0_0>.TangentVector>) {
37+
// CHECK: [[SELF_ALLOC:%.*]] = alloc_stack [dynamic_lifetime] $Tensor<τ_0_0>, var, name "self"
38+
39+
// Original error:
40+
// SIL memory lifetime failure in @AD__$s5crash6TensorVyACyxGx_ADtcfC__vjp_src_0_wrt_1_l: memory is not initialized, but should
41+
// memory location: %29 = struct_element_addr %5 : $*Tensor<τ_0_0>, #Tensor.x // user: %30
42+
// at instruction: destroy_addr %29 : $*τ_0_0 // id: %30

0 commit comments

Comments
 (0)