Skip to content

[AutoDiff] Crash due to ownership error related to Optional TangentVector in certain cases. #82477

Open
@fibrechannelscsi

Description

@fibrechannelscsi

Description

The following code causes a compiler crash when built in Debug mode. This appears to affect 6.1 and 6.2-series toolchains. A selected 6.0.3 toolchain generates a compilation error instead.

Here are some details of the crash outside of the stack trace itself:

Begin Error in Function: '$s7dfThree1FVAASdRszSdRs_rlE1oSaySaySfGGSgyFTJpSpSr'
Found an operand with a value that is not compatible with the operand's operand ownership kind map.
Value:   %66 = copy_value %0 : $Optional<Array<Array<Float>>>.TangentVector // user: %134
Value Ownership Kind: owned
Instruction:
     %66 = copy_value %0 : $Optional<Array<Array<Float>>>.TangentVector // user: %134
->   %134 = struct_extract %66 : $Optional<Array<Array<Float>>>.TangentVector, #Optional.TangentVector.value
Constraint: <Constraint Kind:guaranteed LifetimeConstraint:NonLifetimeEnding>
End Error in Function: '$s7dfThree1FVAASdRszSdRs_rlE1oSaySaySfGGSgyFTJpSpSr'
Found ownership error?!

Reproduction

Copy and paste the code below into a new project, and attempt to compile in Debug mode.

import Foundation; import _Differentiation
struct F<I, T>: A {}
extension F where I == Double, T == Double {
    @differentiable(reverse) func o() -> [[Float]]? {
        guard let j = self.i() else {return nil}
        return j.g().map { $0.map(Float.init) }
    }
}
extension F: Differentiable where T: Differentiable {}
protocol A<T> {associatedtype T}
extension A {
    func g() -> [[T]] {return [[T]]()}
    func i() -> Self? {return self}
}

Stack dump

1.	Apple Swift version 6.2-dev (LLVM 5fbc818cf26c90b, Swift 2e1897356956e43)
2.	Compiling with effective version 5.10
3.	While evaluating request ExecuteSILPipelineRequest(Run pipelines { Mandatory Diagnostic Passes + Enabling Optimization Passes } on SIL for dfThree)
4.	While running pass #299 SILModuleTransform "Differentiation".
5.	While processing // differentiability witness for F<>.o()
sil_differentiability_witness [serialized] [reverse] [parameters 0] [results 0] @$s7dfThree1FVAASdRszSdRs_rlE1oSaySaySfGGSgyF : $@convention(method) (F<Double, Double>) -> @owned Optional<Array<Array<Float>>> {
}

 on SIL function "@$s7dfThree1FVAASdRszSdRs_rlE1oSaySaySfGGSgyF".
 for 'o()' (at /Users/user/dfThree/dfThree/main.swift:4:30)
6.	While generating VJP for SIL function "@$s7dfThree1FVAASdRszSdRs_rlE1oSaySaySfGGSgyF".
 for 'o()' (at /Users/user/dfThree/dfThree/main.swift:4:30)
7.	While generating pullback for SIL function "@$s7dfThree1FVAASdRszSdRs_rlE1oSaySaySfGGSgyF".
 for 'o()' (at /Users/user/dfThree/dfThree/main.swift:4:30)
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           0x0000000105ca5e58 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x0000000105ca4584 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x0000000105ca64a0 SignalHandler(int, __siginfo*, void*) + 296
3  libsystem_platform.dylib 0x0000000198884624 _sigtramp + 56
4  libsystem_pthread.dylib  0x000000019884a88c pthread_kill + 296
5  libsystem_c.dylib        0x0000000198753c60 abort + 124
6  swift-frontend           0x000000010078eaf0 swift::DiagnosticHelper::create(swift::CompilerInstance&, swift::CompilerInvocation const&, llvm::ArrayRef<char const*>, llvm::raw_pwrite_stream&, bool) + 0
7  swift-frontend           0x0000000105c24288 llvm::report_fatal_error(llvm::Twine const&, bool) + 256
8  swift-frontend           0x0000000105c24188 llvm::report_fatal_error(llvm::Twine const&, bool) + 0
9  swift-frontend           0x00000001013ff34c swift::LinearLifetimeChecker::ErrorBuilder::tryDumpErrorCounter() const + 0
10 swift-frontend           0x0000000101407184 swift::SILInstruction::verifyOperandOwnership(swift::SILModuleConventions*) const + 680
11 swift-frontend           0x0000000100aabca8 swift::SILBuilder::createStructExtract(swift::SILLocation, swift::SILValue, swift::VarDecl*, swift::SILType, swift::ValueOwnershipKind) + 236
12 swift-frontend           0x0000000100cfe2f8 swift::autodiff::PullbackCloner::Implementation::visitEnumInst(swift::EnumInst*) + 440
13 swift-frontend           0x0000000100cf7484 swift::autodiff::PullbackCloner::Implementation::visit(swift::SILInstruction*) + 200
14 swift-frontend           0x0000000100cf3254 swift::autodiff::PullbackCloner::Implementation::visitSILBasicBlock(swift::SILBasicBlock*) + 764
15 swift-frontend           0x0000000100cf01fc swift::autodiff::PullbackCloner::Implementation::run() + 5716
16 swift-frontend           0x0000000100ceeb70 swift::autodiff::PullbackCloner::run() + 24
17 swift-frontend           0x0000000100d0ccd0 swift::autodiff::VJPCloner::Implementation::run() + 1268
18 swift-frontend           0x0000000100d0d49c swift::autodiff::VJPCloner::run() + 24
19 swift-frontend           0x0000000100e59980 (anonymous namespace)::DifferentiationTransformer::canonicalizeDifferentiabilityWitness(swift::SILDifferentiabilityWitness*, swift::autodiff::DifferentiationInvoker, swift::SerializedKind_t) + 6056
20 swift-frontend           0x0000000100e577c0 (anonymous namespace)::Differentiation::run() + 956
21 swift-frontend           0x0000000100ef905c swift::SILPassManager::runModulePass(unsigned int) + 856
22 swift-frontend           0x0000000100efb47c swift::SILPassManager::execute() + 624
23 swift-frontend           0x0000000100ef5e98 swift::SILPassManager::executePassPipelinePlan(swift::SILPassPipelinePlan const&) + 72
24 swift-frontend           0x0000000100ef5e18 swift::ExecuteSILPipelineRequest::evaluate(swift::Evaluator&, swift::SILPipelineExecutionDescriptor) const + 68
25 swift-frontend           0x0000000100f1b5fc swift::SimpleRequest<swift::ExecuteSILPipelineRequest, std::__1::tuple<> (swift::SILPipelineExecutionDescriptor), (swift::RequestFlags)1>::evaluateRequest(swift::ExecuteSILPipelineRequest const&, swift::Evaluator&) + 28
26 swift-frontend           0x0000000100efd008 swift::ExecuteSILPipelineRequest::OutputType swift::Evaluator::getResultUncached<swift::ExecuteSILPipelineRequest, swift::ExecuteSILPipelineRequest::OutputType swift::evaluateOrFatal<swift::ExecuteSILPipelineRequest>(swift::Evaluator&, swift::ExecuteSILPipelineRequest)::'lambda'()>(swift::ExecuteSILPipelineRequest const&, swift::ExecuteSILPipelineRequest::OutputType swift::evaluateOrFatal<swift::ExecuteSILPipelineRequest>(swift::Evaluator&, swift::ExecuteSILPipelineRequest)::'lambda'()) + 204
27 swift-frontend           0x0000000100ef6088 swift::executePassPipelinePlan(swift::SILModule*, swift::SILPassPipelinePlan const&, bool, swift::irgen::IRGenModule*) + 64
28 swift-frontend           0x0000000100efe5dc swift::runSILDiagnosticPasses(swift::SILModule&) + 192
29 swift-frontend           0x00000001007a5360 swift::CompilerInstance::performSILProcessing(swift::SILModule*) + 80
30 swift-frontend           0x00000001005656ac 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*) + 820
31 swift-frontend           0x0000000100564d0c swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 468
32 swift-frontend           0x00000001005714d0 withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) + 164
33 swift-frontend           0x0000000100566b04 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 716
34 swift-frontend           0x00000001005662c0 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 2312
35 swift-frontend           0x000000010030a77c swift::mainEntry(int, char const**) + 3064
36 dyld                     0x00000001984aab98 start + 6076

Expected behavior

The program should compile successfully, or, the compiler should indicate that the function is not differentiable, as applicable.

Environment

Of the toolchains I've tested, this crashes with:
swift-6.2-DEVELOPMENT-SNAPSHOT-2025-06-17-a
swift-6.1-DEVELOPMENT-SNAPSHOT-2025-03-25-a

The compiler indicates the function is not differentiable (and does not crash) with:
swift-6.0.3-RELEASE (2024-12-10(a))

Additional information

For an affected toolchain, if we delete the line containing guard let j and replace the following line with:
return self.i()!.g().map { $0.map(Float.init) }
we get a different stack trace:

1.	Apple Swift version 6.2-dev (LLVM 5fbc818cf26c90b, Swift 2e1897356956e43)
2.	Compiling with effective version 5.10
3.	While evaluating request ExecuteSILPipelineRequest(Run pipelines { Mandatory Diagnostic Passes + Enabling Optimization Passes } on SIL for dfThree)
4.	While running pass #299 SILModuleTransform "Differentiation".
5.	While processing // differentiability witness for F<>.o()
sil_differentiability_witness [serialized] [reverse] [parameters 0] [results 0] @$s7dfThree1FVAASdRszSdRs_rlE1oSaySaySfGGSgyF : $@convention(method) (F<Double, Double>) -> @owned Optional<Array<Array<Float>>> {
}

 on SIL function "@$s7dfThree1FVAASdRszSdRs_rlE1oSaySaySfGGSgyF".
 for 'o()' (at /Users/user/dfThree/dfThree/main.swift:4:30)
6.	While generating VJP for SIL function "@$s7dfThree1FVAASdRszSdRs_rlE1oSaySaySfGGSgyF".
 for 'o()' (at /Users/user/dfThree/dfThree/main.swift:4:30)
7.	While generating pullback for SIL function "@$s7dfThree1FVAASdRszSdRs_rlE1oSaySaySfGGSgyF".
 for 'o()' (at /Users/user/dfThree/dfThree/main.swift:4:30)
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           0x0000000106859e58 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x0000000106858584 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x000000010685a4a0 SignalHandler(int, __siginfo*, void*) + 296
3  libsystem_platform.dylib 0x0000000198884624 _sigtramp + 56
4  libsystem_pthread.dylib  0x000000019884a88c pthread_kill + 296
5  libsystem_c.dylib        0x0000000198753c60 abort + 124
6  swift-frontend           0x0000000101342af0 swift::DiagnosticHelper::create(swift::CompilerInstance&, swift::CompilerInvocation const&, llvm::ArrayRef<char const*>, llvm::raw_pwrite_stream&, bool) + 0
7  swift-frontend           0x00000001067d8288 llvm::report_fatal_error(llvm::Twine const&, bool) + 256
8  swift-frontend           0x00000001067d8188 llvm::report_fatal_error(llvm::Twine const&, bool) + 0
9  swift-frontend           0x00000001018a81f8 swift::autodiff::PullbackCloner::Implementation::visitSILBasicBlock(swift::SILBasicBlock*) + 4768
10 swift-frontend           0x00000001018a41fc swift::autodiff::PullbackCloner::Implementation::run() + 5716
11 swift-frontend           0x00000001018a2b70 swift::autodiff::PullbackCloner::run() + 24
12 swift-frontend           0x00000001018c0cd0 swift::autodiff::VJPCloner::Implementation::run() + 1268
13 swift-frontend           0x00000001018c149c swift::autodiff::VJPCloner::run() + 24
14 swift-frontend           0x0000000101a0d980 (anonymous namespace)::DifferentiationTransformer::canonicalizeDifferentiabilityWitness(swift::SILDifferentiabilityWitness*, swift::autodiff::DifferentiationInvoker, swift::SerializedKind_t) + 6056
15 swift-frontend           0x0000000101a0b7c0 (anonymous namespace)::Differentiation::run() + 956
16 swift-frontend           0x0000000101aad05c swift::SILPassManager::runModulePass(unsigned int) + 856
17 swift-frontend           0x0000000101aaf47c swift::SILPassManager::execute() + 624
18 swift-frontend           0x0000000101aa9e98 swift::SILPassManager::executePassPipelinePlan(swift::SILPassPipelinePlan const&) + 72
19 swift-frontend           0x0000000101aa9e18 swift::ExecuteSILPipelineRequest::evaluate(swift::Evaluator&, swift::SILPipelineExecutionDescriptor) const + 68
20 swift-frontend           0x0000000101acf5fc swift::SimpleRequest<swift::ExecuteSILPipelineRequest, std::__1::tuple<> (swift::SILPipelineExecutionDescriptor), (swift::RequestFlags)1>::evaluateRequest(swift::ExecuteSILPipelineRequest const&, swift::Evaluator&) + 28
21 swift-frontend           0x0000000101ab1008 swift::ExecuteSILPipelineRequest::OutputType swift::Evaluator::getResultUncached<swift::ExecuteSILPipelineRequest, swift::ExecuteSILPipelineRequest::OutputType swift::evaluateOrFatal<swift::ExecuteSILPipelineRequest>(swift::Evaluator&, swift::ExecuteSILPipelineRequest)::'lambda'()>(swift::ExecuteSILPipelineRequest const&, swift::ExecuteSILPipelineRequest::OutputType swift::evaluateOrFatal<swift::ExecuteSILPipelineRequest>(swift::Evaluator&, swift::ExecuteSILPipelineRequest)::'lambda'()) + 204
22 swift-frontend           0x0000000101aaa088 swift::executePassPipelinePlan(swift::SILModule*, swift::SILPassPipelinePlan const&, bool, swift::irgen::IRGenModule*) + 64
23 swift-frontend           0x0000000101ab25dc swift::runSILDiagnosticPasses(swift::SILModule&) + 192
24 swift-frontend           0x0000000101359360 swift::CompilerInstance::performSILProcessing(swift::SILModule*) + 80
25 swift-frontend           0x00000001011196ac 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*) + 820
26 swift-frontend           0x0000000101118d0c swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 468
27 swift-frontend           0x00000001011254d0 withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) + 164
28 swift-frontend           0x000000010111ab04 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 716
29 swift-frontend           0x000000010111a2c0 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 2312
30 swift-frontend           0x0000000100ebe77c swift::mainEntry(int, char const**) + 3064
31 dyld                     0x00000001984aab98 start + 6076

An unaffected toolchain will indicate the function is not differentiable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.crashBug: A crash, i.e., an abnormal termination of softwaretriage neededThis issue needs more specific labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions