swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.57k stars 10.36k forks source link

[AutoDiff] Fatal error of "do not know how to handle this incoming bb argument" when using a throwing function inside a differentiable function #70819

Open BradLarson opened 10 months ago

BradLarson commented 10 months ago

Description

The use of a differentiable throwing function within an encapsulating differentiable function leads to a fatal error at compile time of do not know how to handle this incoming bb argument. This is similar to the case in #57523, but instead of the throwing function being used directly in gradient(at:of:) it is instead surrounded by a non-throwing differentiable function.

Reproduction

The following simple program reproduces this in a regular swiftc build:

import _Differentiation

@differentiable(reverse)
func test1(input: Float) throws -> Float {
    return input
}

@differentiable(reverse)
func test2(input: Float) -> Float {
    do {
        return try test1(input: input)
    } catch {
        return 0.0
    }
}

let (value, gradient) = valueWithGradient(at: 1.0, of: test2)
print("Value: \(value), gradient: \(gradient)")

The trace produced looks something like the following:

error: compile command failed due to signal 6 (use -v to see invocation)
<unknown>:0: error: fatal error encountered during compilation; please submit a bug report (https://swift.org/contributing/#reporting-bugs)
<unknown>:0: note: do not know how to handle this incoming bb argument
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the crash backtrace.
Stack dump:
0.  Program arguments: /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2023-12-07-a.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file /Users/larson/Desktop/throwstest.swift -target arm64-apple-macosx13.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.sdk -color-diagnostics -new-driver-path /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2023-12-07-a.xctoolchain/usr/bin/swift-driver -empty-abi-descriptor -resource-dir /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2023-12-07-a.xctoolchain/usr/lib/swift -module-name throwstest -target-sdk-version 14.2 -target-sdk-name macosx14.2 -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.sdk/usr/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.sdk/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.sdk/usr/local/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.sdk/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -external-plugin-path /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/local/lib/swift/host/plugins#/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/usr/bin/swift-plugin-server -plugin-path /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2023-12-07-a.xctoolchain/usr/lib/swift/host/plugins -plugin-path /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2023-12-07-a.xctoolchain/usr/local/lib/swift/host/plugins -o /var/folders/6y/ghmhq_xj3xq100vsttqqn2lc0000gq/T/TemporaryDirectory.jYso3S/throwstest-1.o
1.  Apple Swift version 5.11-dev (LLVM 91cd37b9110872c, Swift 703a4719b0c6f3a)
2.  Compiling with the current language version
3.  While evaluating request ExecuteSILPipelineRequest(Run pipelines { Mandatory Diagnostic Passes + Enabling Optimization Passes } on SIL for throwstest)
4.  While running pass #70 SILModuleTransform "Differentiation".
5.  While processing // differentiability witness for test2(input:)
sil_differentiability_witness hidden [reverse] [parameters 0] [results 0] @$s10throwstest5test25inputS2f_tF : $@convention(thin) (Float) -> Float {
}

 on SIL function "@$s10throwstest5test25inputS2f_tF".
 for 'test2(input:)' (at /Users/larson/Desktop/throwstest.swift:9:1)
6.  While generating VJP for SIL function "@$s10throwstest5test25inputS2f_tF".
 for 'test2(input:)' (at /Users/larson/Desktop/throwstest.swift:9:1)
7.  While generating pullback for SIL function "@$s10throwstest5test25inputS2f_tF".
 for 'test2(input:)' (at /Users/larson/Desktop/throwstest.swift:9:1)
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           0x00000001061db150 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x00000001061d98ac llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x00000001061db7a0 SignalHandler(int) + 304
3  libsystem_platform.dylib 0x000000019cd5ea24 _sigtramp + 56
4  libsystem_pthread.dylib  0x000000019cd2fc28 pthread_kill + 288
5  libsystem_c.dylib        0x000000019cc3dae8 abort + 180
6  swift-frontend           0x0000000100d8e848 PrettyStackTraceFrontend::~PrettyStackTraceFrontend() + 0
7  swift-frontend           0x0000000106154f84 llvm::report_fatal_error(llvm::Twine const&, bool) + 268
8  swift-frontend           0x0000000106154e78 llvm::report_fatal_error(llvm::Twine const&, bool) + 0
9  swift-frontend           0x000000010148e5dc swift::autodiff::PullbackCloner::Implementation::visitSILBasicBlock(swift::SILBasicBlock*) + 2680
10 swift-frontend           0x000000010148adcc swift::autodiff::PullbackCloner::Implementation::run() + 5276
11 swift-frontend           0x00000001014898f8 swift::autodiff::PullbackCloner::run() + 24
12 swift-frontend           0x00000001014a7670 swift::autodiff::VJPCloner::Implementation::run() + 1368
13 swift-frontend           0x00000001014a7da4 swift::autodiff::VJPCloner::run() + 24
14 swift-frontend           0x00000001015f05d4 (anonymous namespace)::DifferentiationTransformer::canonicalizeDifferentiabilityWitness(swift::SILDifferentiabilityWitness*, swift::autodiff::DifferentiationInvoker, swift::IsSerialized_t) + 6212
15 swift-frontend           0x00000001015ee460 (anonymous namespace)::Differentiation::run() + 1032
16 swift-frontend           0x00000001016a0a8c swift::SILPassManager::runModulePass(unsigned int) + 976
17 swift-frontend           0x00000001016a6b60 swift::SILPassManager::execute() + 624
18 swift-frontend           0x000000010169d950 swift::SILPassManager::executePassPipelinePlan(swift::SILPassPipelinePlan const&) + 68
19 swift-frontend           0x000000010169d8d8 swift::ExecuteSILPipelineRequest::evaluate(swift::Evaluator&, swift::SILPipelineExecutionDescriptor) const + 68
20 swift-frontend           0x00000001016e0794 swift::SimpleRequest<swift::ExecuteSILPipelineRequest, std::__1::tuple<> (swift::SILPipelineExecutionDescriptor), (swift::RequestFlags)1>::evaluateRequest(swift::ExecuteSILPipelineRequest const&, swift::Evaluator&) + 28
21 swift-frontend           0x00000001016c8510 llvm::Expected<swift::ExecuteSILPipelineRequest::OutputType> swift::Evaluator::getResultUncached<swift::ExecuteSILPipelineRequest>(swift::ExecuteSILPipelineRequest const&) + 268
22 swift-frontend           0x000000010169db40 swift::executePassPipelinePlan(swift::SILModule*, swift::SILPassPipelinePlan const&, bool, swift::irgen::IRGenModule*) + 84
23 swift-frontend           0x00000001016cb4f8 swift::runSILDiagnosticPasses(swift::SILModule&) + 192
24 swift-frontend           0x0000000100f77740 swift::CompilerInstance::performSILProcessing(swift::SILModule*) + 80
25 swift-frontend           0x0000000100d87b84 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*) + 792
26 swift-frontend           0x0000000100d87284 swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 596
27 swift-frontend           0x0000000100d96ab8 withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) + 160
28 swift-frontend           0x0000000100d89e78 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 704
29 swift-frontend           0x0000000100d88e3c swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 2632
30 swift-frontend           0x0000000100c30c6c swift::mainEntry(int, char const**) + 2192
31 dyld                     0x000000019c9d7f28 start + 2236
error: fatalError

Expected behavior

The above should compile without error, and automatic differentiation should work correctly through the throwing function.

Environment

This is not a new regression, and is present in nightly toolchain snapshots and releases on various platforms dating back through at least the last year.

Additional information

No response

asl commented 9 months ago

We need to provide proper diagnostics that one cannot differentiate such code

asl commented 9 months ago

I think we need to provide better diagnostics here (likely during the activity analysis or so, seeing if error result is active).