Skip to content

Commit ec38ce6

Browse files
committed
[AutoDiff] Fix derivative forwarding thunk linkage.
Make derivative forwarding thunks use original function's linkage instead of the derivative function's, stripping external. This is consistent with the linkage of differentiability witnesses. Clarify AutoDiff linkage-related comments. Resolves TF-1160: AutoDiff symbol TBDGen error.
1 parent 528479e commit ec38ce6

File tree

4 files changed

+49
-6
lines changed

4 files changed

+49
-6
lines changed

lib/SILGen/SILGen.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -839,8 +839,8 @@ void SILGenModule::emitDifferentiabilityWitness(
839839
SILDifferentiabilityWitnessKey key{originalFunction->getName(), silConfig};
840840
auto *diffWitness = M.lookUpDifferentiabilityWitness(key);
841841
if (!diffWitness) {
842-
// Strip external from linkage of original function.
843-
// Necessary for Clang-imported functions, which have external linkage.
842+
// Differentiability witnesses have the same linkage as the original
843+
// function, stripping external.
844844
auto linkage = stripExternalFromLinkage(originalFunction->getLinkage());
845845
diffWitness = SILDifferentiabilityWitness::createDefinition(
846846
M, linkage, originalFunction, silConfig.parameterIndices,

lib/SILGen/SILGenPoly.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3941,14 +3941,17 @@ SILFunction *SILGenModule::getOrCreateCustomDerivativeThunk(
39413941

39423942
auto loc = customDerivativeFn->getLocation();
39433943
SILGenFunctionBuilder fb(*this);
3944-
// This thunk is publicly exposed and cannot be transparent.
3945-
// Instead, mark it as "always inline" for optimization.
3944+
// Derivative thunks have the same linkage as the original function, stripping
3945+
// external.
3946+
auto linkage = stripExternalFromLinkage(originalFn->getLinkage());
39463947
auto *thunk = fb.getOrCreateFunction(
3947-
loc, name, customDerivativeFn->getLinkage(), thunkFnTy, IsBare,
3948-
IsNotTransparent, customDerivativeFn->isSerialized(),
3948+
loc, name, linkage, thunkFnTy, IsBare, IsNotTransparent,
3949+
customDerivativeFn->isSerialized(),
39493950
customDerivativeFn->isDynamicallyReplaceable(),
39503951
customDerivativeFn->getEntryCount(), IsThunk,
39513952
customDerivativeFn->getClassSubclassScope());
3953+
// This thunk may be publicly exposed and cannot be transparent.
3954+
// Instead, mark it as "always inline" for optimization.
39523955
thunk->setInlineStrategy(AlwaysInline);
39533956
if (!thunk->empty())
39543957
return thunk;

test/AutoDiff/Sema/derivative_attr_type_checking.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,27 @@ fileprivate func _fileprivate_original_fileprivate_derivative(_ x: Float) -> (va
837837
fatalError()
838838
}
839839

840+
func internal_original_usablefrominline_derivative(_ x: Float) -> Float { x }
841+
@usableFromInline
842+
@derivative(of: internal_original_usablefrominline_derivative)
843+
func _internal_original_usablefrominline_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
844+
fatalError()
845+
}
846+
847+
func internal_original_inlinable_derivative(_ x: Float) -> Float { x }
848+
@inlinable
849+
@derivative(of: internal_original_inlinable_derivative)
850+
func _internal_original_inlinable_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
851+
fatalError()
852+
}
853+
854+
func internal_original_alwaysemitintoclient_derivative(_ x: Float) -> Float { x }
855+
@_alwaysEmitIntoClient
856+
@derivative(of: internal_original_alwaysemitintoclient_derivative)
857+
func _internal_original_alwaysemitintoclient_derivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
858+
fatalError()
859+
}
860+
840861
// MARK: - Original function visibility < derivative function visibility
841862

842863
@usableFromInline
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-swift-frontend -c %s -verify
2+
// REQUIRES: asserts
3+
4+
// TF-1160: Linker error for `@usableFromInline` derivative function but
5+
// non-`@usableFromInline` internal original function.
6+
7+
import _Differentiation
8+
9+
func internalOriginal(_ x: Float) -> Float { x }
10+
11+
@usableFromInline
12+
@derivative(of: internalOriginal)
13+
func usableFromInlineDerivative(_ x: Float) -> (value: Float, pullback: (Float) -> Float) {
14+
(x, { $0 })
15+
}
16+
17+
// Original error: type-checking passes but TBDGen is not consistent with IRGen.
18+
// <unknown>:0: error: symbol 'AD__$s4main16internalOriginalyS2fF__vjp_src_0_wrt_0' (AD__$s4main16internalOriginalyS2fF__vjp_src_0_wrt_0) is in generated IR file, but not in TBD file
19+
// <unknown>:0: error: please file a radar or open a bug on bugs.swift.org with this code, and add -Xfrontend -validate-tbd-against-ir=none to squash the errors

0 commit comments

Comments
 (0)