Skip to content

Commit d9c3a84

Browse files
authored
[AutoDiff] Fix semantic member accessor linear map structs. (#31745)
Ensure that semantic member accesors have empty linear map structs. Semantic member accessor VJPs do not accumulate any callee pullbacks. Resolves SR-12800: SIL verification error.
1 parent 09db813 commit d9c3a84

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

lib/SILOptimizer/Differentiation/LinearMapInfo.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,11 @@ void LinearMapInfo::generateDifferentiationDataStructures(
408408
linearMapStructEnumFields.insert({linearMapStruct, traceEnumField});
409409
}
410410

411+
// Do not add linear map fields for semantic member accessors, which have
412+
// special-case pullback generation. Linear map structs should be empty.
413+
if (isSemanticMemberAccessor(original))
414+
return;
415+
411416
// Add linear map fields to the linear map structs.
412417
for (auto &origBB : *original) {
413418
for (auto &inst : origBB) {

test/AutoDiff/SILOptimizer/property_wrappers.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-swift-frontend -emit-sil -verify %s %S/Inputs/nontrivial_loadable_type.swift
2+
// REQUIRES: asserts
23

34
// Test property wrapper differentiation coverage for a variety of property
45
// types: trivial, non-trivial loadable, and address-only.
@@ -25,17 +26,35 @@ struct Wrapper<Value> {
2526
}
2627
}
2728

29+
// `DifferentiableWrapper` conditionally conforms to `Differentiable`.
30+
@propertyWrapper
31+
struct DifferentiableWrapper<Value> {
32+
private var value: Value
33+
var wrappedValue: Value { // computed property
34+
get { value }
35+
set { value = newValue }
36+
}
37+
38+
init(wrappedValue: Value) {
39+
self.value = wrappedValue
40+
}
41+
}
42+
extension DifferentiableWrapper: Differentiable where Value: Differentiable {}
43+
2844
// MARK: Types with wrapped properties
2945

3046
struct Struct: Differentiable {
3147
@Wrapper @SimpleWrapper var trivial: Float = 10
3248
@Wrapper @SimpleWrapper var tracked: Tracked<Float> = 20
3349
@Wrapper @SimpleWrapper var nontrivial: NontrivialLoadable<Float> = 30
50+
// Tests SR-12800: semantic member accessors should have empty linear map structs.
51+
@DifferentiableWrapper var differentiableWrapped: Float = 40
3452

3553
static func testGetters() {
3654
let _: @differentiable (Self) -> Float = { $0.trivial }
3755
let _: @differentiable (Self) -> Tracked<Float> = { $0.tracked }
3856
let _: @differentiable (Self) -> NontrivialLoadable<Float> = { $0.nontrivial }
57+
let _: @differentiable (Self) -> Float = { $0.differentiableWrapped }
3958
}
4059

4160
static func testSetters() {
@@ -45,6 +64,8 @@ struct Struct: Differentiable {
4564
{ $0.tracked = $1 }
4665
let _: @differentiable (inout Self, NontrivialLoadable<Float>) -> Void =
4766
{ $0.nontrivial = $1 }
67+
let _: @differentiable (inout Self, Float) -> Void =
68+
{ $0.differentiableWrapped = $1 }
4869
}
4970
}
5071

0 commit comments

Comments
 (0)