Skip to content

Type reconstruction fails for some @differentiable functions when unit tests are built for Profiling. #63207

@fibrechannelscsi

Description

@fibrechannelscsi

Description
The compiler crashes with an error message indicating that it failed to reconstruct the type for what appears to be a differentiable function, in the case of the below code.

Steps to reproduce

  1. Use the code below in order to generate a library.
import _Differentiation
public struct F<I: Equatable, D> {public init() {}}
extension F: Equatable where D: Equatable {}
extension F: Differentiable where D: Differentiable, D.TangentVector == D {}
extension F: AdditiveArithmetic where D: AdditiveArithmetic {
    public static func + (lhs: F<I, D>, rhs: F<I, D>) -> F<I, D> {return lhs}
    public static func - (lhs: F<I, D>, rhs: F<I, D>) -> F<I, D> {return lhs}
    public static var zero: F<I, D> {return F<I, D>()}
}
public extension F where D: Differentiable, D == D.TangentVector {
    mutating func assign1(_ series: S<I, D>, at key: String?) {fatalError()}
    @differentiable(reverse)
    mutating func assign0(_ series: S<I, D>) {self.assign1(series, at: nil)}
    @inlinable
    @differentiable(reverse)
    mutating func assignMain(_ series: S<I, D>) {self.assign0(series)}
    @derivative(of: assign0)
    mutating func vjpAssign_(series: S<I, D>) -> (value: Void, pullback: (inout Self.TangentVector) -> S<I, D>.TangentVector)
    {
        return ((), {_ in S<I, D>.TangentVector.zero})
    }
//    @derivative(of: assignMain)
//    mutating func vjpAssignMain(series: S<I, D>) -> (value: Void, pullback: (inout Self.TangentVector) -> S<I, D>.TangentVector)
//    {
//        return ((), {_ in S<I, D>.TangentVector.zero})
//    }
    
}
public struct S<I, D> {public init(){}}
extension S: Equatable where D: Equatable {
    public static func == (lhs: S<I, D>, rhs: S<I, D>) -> Bool {fatalError()}
}
extension S: Differentiable where D: Differentiable, D.TangentVector == D{public typealias TangentVector = S<I, D>}
extension S: AdditiveArithmetic where D: AdditiveArithmetic {
    public static func + (_ lhs: Self, _ rhs: Self) -> Self {fatalError()}
    public static func - (_ lhs: Self, _ rhs: Self) -> Self {fatalError()}
    public static var zero: Self {fatalError()}
}
  1. Specify the library generated by the code above as one of the imports to the unit test code below:
import _Differentiation
import PlayGround //Specify custom library name here.
import XCTest
class UnitTests: XCTestCase {
    func testA(){
        @differentiable(reverse)
        func a(input: S<Double, Double>) -> F<Double, Double> {
            var f = F<Double, Double>()
            f.assignMain(input)
            return f
        }
    }
}
  1. In Xcode, right click and select Profile "testA()".

The compiler will generate an error that looks like:

Failed to reconstruct type for $s10PlayGround09_AD__$s10a131Ground1FVAA16_Differentiation14DifferentiableR_13TangentVectorAdEPQy_Rs_rlE10assignMainyyAA1SVyxq_GF_bb0__PB__src_0_wrt_0_1_SQRz16_gh4R_13ij7AaBPQy_M5_r0_lVyS2dGD
Original type:
(bound_generic_struct_type decl=PlayGround.(file)._AD__$s10PlayGround1FVAA16_Differentiation14DifferentiableR_13TangentVectorAdEPQy_Rs_rlE10assignMainyyAA1SVyxq_GF_bb0__PB__src_0_wrt_0_1_SQRz16_Differentiation14DifferentiableR_13TangentVectorAaBPQy_Rs_r0_l
  (struct_type decl=Swift.(file).Double)
  (struct_type decl=Swift.(file).Double))

Additional stack information:

1.	Apple Swift version 5.9-dev (LLVM c48958355f7507c, Swift f26f810cc8406ef)
2.	Compiling with the current language version
3.	While emitting IR SIL function "@$s10PlayGround1FVAA16_Differentiation14DifferentiableR_13TangentVectorAdEPQy_Rs_rlE10assignMainyyAA1SVyxq_GFSQRzAdER_AHRs_r0_lTJpSSpSrSd_SdTg5".
 for <<debugloc at "<compiler-generated>":0:0>>Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0  swift-frontend           0x000000010948d5c8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x000000010948c84c llvm::sys::RunSignalHandlers() + 128
2  swift-frontend           0x000000010948dc08 SignalHandler(int) + 304
3  libsystem_platform.dylib 0x000000018d1314c4 _sigtramp + 56
4  libsystem_pthread.dylib  0x000000018d119ee0 pthread_kill + 288
5  libsystem_c.dylib        0x000000018d054340 abort + 168
6  swift-frontend           0x0000000109527c6c (anonymous namespace)::IRGenDebugInfoImpl::getOrCreateType(swift::irgen::DebugTypeInfo) (.cold.8) + 0
7  swift-frontend           0x0000000104f972f0 (anonymous namespace)::IRGenDebugInfoImpl::getOrCreateType(swift::irgen::DebugTypeInfo) + 3436
8  swift-frontend           0x0000000104f97aac (anonymous namespace)::IRGenDebugInfoImpl::createParameterType(llvm::SmallVectorImpl<llvm::Metadata*>&, swift::SILType) + 132
9  swift-frontend           0x0000000104f977c0 (anonymous namespace)::IRGenDebugInfoImpl::createParameterTypes(swift::CanTypeWrapper<swift::SILFunctionType>) + 404
10 swift-frontend           0x0000000104f90f3c (anonymous namespace)::IRGenDebugInfoImpl::emitFunction(swift::SILDebugScope const*, llvm::Function*, swift::SILFunctionTypeRepresentation, swift::SILType, swift::DeclContext*, llvm::StringRef) + 1720
11 swift-frontend           0x0000000104f917e8 (anonymous namespace)::IRGenDebugInfoImpl::emitFunction(swift::SILFunction&, llvm::Function*) + 160
12 swift-frontend           0x0000000104fcabdc (anonymous namespace)::IRGenSILFunction::emitSILFunction() + 880
13 swift-frontend           0x0000000104fca338 swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 920
14 swift-frontend           0x0000000104e849a8 swift::irgen::IRGenerator::emitLazyDefinitions() + 1400
15 swift-frontend           0x0000000104f7bcc4 swift::performIRGeneration(swift::ModuleDecl*, swift::IRGenOptions const&, swift::TBDGenOptions const&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >, llvm::StringRef, swift::PrimarySpecificPaths const&, llvm::ArrayRef<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, llvm::GlobalVariable**) + 1524
16 swift-frontend           0x0000000104bb2518 performCompileStepsPostSILGen(swift::CompilerInstance&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, int&, swift::FrontendObserver*) + 1608
17 swift-frontend           0x0000000104bb1b38 swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 1100
18 swift-frontend           0x0000000104bc063c withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) + 160
19 swift-frontend           0x0000000104bb361c swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 3204
20 swift-frontend           0x0000000104a09414 swift::mainEntry(int, char const**) + 3304
21 dyld                     0x00000001122e5088 start + 516

Expected behavior
The test should run successfully. Although many functions and computed properties are denoted as fatalError(), none of these are executed since the function a is not actually called. Namely, the type information should be able to be reconstructed without error.

Environment

  • Swift compiler version info: 2023-01-19a. Fails with versions as far back as 2022-07-15a. The type reconstruction succeeds on 2022-05-23a, however.
  • Xcode version info: 13.3 (13E113)
  • Deployment target: iOS 12.3.1, ARM64.

Additional context
If the 5 lines in code block 1 are uncommented, then building testA for profiling succeeds. Namely, manual specification of @derivative(of: assignMain) causes the build to succeed.

Metadata

Metadata

Assignees

Labels

AutoDiffbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselfcrashBug: A crash, i.e., an abnormal termination of softwaredebug infoArea → compiler → IRGen: Debug information emissionmanglingArea → compiler: Mangling

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions