Skip to content

Assertion failure when attempting to write via a WritableKeyPath to a Differentiable item. #63728

@fibrechannelscsi

Description

@fibrechannelscsi

Description
The compiler generates an assertion failure when attempting to compile the code listed below.

Steps to reproduce
Paste the code below into a single file and attempt to compile.

import _Differentiation
import Foundation
func a() throws {
    let keyPaths = (readable: [String: KeyPath<T, Double>](), writable: [String: WritableKeyPath<T, Double>]())
    @differentiable(reverse)
    func f(p: PAndT) -> Double {
        var mutableP = p
        let s = p.p.e
        var sArray: [[Double]] = []
        sArray.append((s["a"]!.asArray()).map {$0.value})
        mutableP.s = w(mutableP.s, at: keyPaths.writable["a"]!, with: sArray[0][0])
        return mutableP.s[keyPath: keyPaths.writable["a"]!]
    }
}
public struct S<I: SProtocol, D> {public func asArray() -> [(index: I, value: D)] {return [(index: I, value: D)]()}}
struct T: Differentiable {}
struct P: Differentiable {public var e: F<Double, Double>}
struct PAndT: Differentiable{
    @differentiable(reverse) public var p: P
    @differentiable(reverse) public var s: T
}
public struct F<I: SProtocol, D>{
    public func asArray() -> [(index: I, value: D)] {return [(index: I, value: D)]()}
    public subscript(_ name: String) -> S<I, D>? {get { return self.sGet(name) }}
    func sGet(_ name: String) -> S<I, D>? {fatalError("")}
}
public protocol ZProtocol: Differentiable {var z: () -> TangentVector { get }}
public protocol SProtocol: Hashable {}
extension F: Differentiable where D: ZProtocol, D.TangentVector == D {}
public extension ZProtocol {var z: () -> TangentVector {{ Self.TangentVector.zero }}}
extension F: Equatable where I: Equatable, D: Equatable {}
extension Double: SProtocol, ZProtocol {}
@differentiable(reverse where O: Differentiable, M: ZProtocol)
func w<O, M>(_ o: O, at m: WritableKeyPath<O, M>, with v: M) -> O {return o}
@derivative(of: w)
func vjpw<O, M>(_ o: O, at m: WritableKeyPath<O, M>, with v: M) -> (value: O, pullback: (O.TangentVector) -> (O.TangentVector, M.TangentVector)) where O: Differentiable, M: ZProtocol{fatalError("")}

The following assertion fails:

Begin Error in Function: '$s18NewToolchainTester1ayyKF1fL_1pSdAA5PAndTV_tFTJpSUpSr'
Error! Found a leaked owned value that was never consumed.
Value:   %419 = copy_value %414 : $Array<Double>.DifferentiableView

End Error in Function: '$s18NewToolchainTester1ayyKF1fL_1pSdAA5PAndTV_tFTJpSUpSr'
Found ownership error?!
triggering standard assertion failure routine
UNREACHABLE executed at /Users/ec2-user/jenkins/workspace/oss-swift-package-macos/swift/lib/SIL/Verifier/LinearLifetimeCheckerPrivate.h:211!

Stack dump:

1.	Apple Swift version 5.9-dev (LLVM c48958355f7507c, Swift f26f810cc8406ef)
2.	Compiling with the current language version
3.	While evaluating request ExecuteSILPipelineRequest(Run pipelines { Mandatory Diagnostic Passes + Enabling Optimization Passes } on SIL for NewToolchainTester)
4.	While running pass #684 SILModuleTransform "Differentiation".
5.	While processing // differentiability witness for f #1 (p:) in a()
sil_differentiability_witness private [reverse] [parameters 0] [results 0] @$s18NewToolchainTester1ayyKF1fL_1pSdAA5PAndTV_tF : $@convention(thin) (PAndT, @guaranteed (readable: Dictionary<String, KeyPath<T, Double>>, writable: Dictionary<String, WritableKeyPath<T, Double>>)) -> Double {
}

 on SIL function "@$s18NewToolchainTester1ayyKF1fL_1pSdAA5PAndTV_tF".
 for 'f(p:)' (at /Users/user/playground/NewToolchainTester/NewToolchainTester/main.swift:6:5)
6.	While generating VJP for SIL function "@$s18NewToolchainTester1ayyKF1fL_1pSdAA5PAndTV_tF".
 for 'f(p:)' (at /Users/user/playground/NewToolchainTester/NewToolchainTester/main.swift:6:5)
7.	While verifying SIL function "@$s18NewToolchainTester1ayyKF1fL_1pSdAA5PAndTV_tFTJpSUpSr".
 for 'f(p:)' (at /Users/user/playground/NewToolchainTester/NewToolchainTester/main.swift:6:5)
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           0x0000000108bb95c8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x0000000108bb884c llvm::sys::RunSignalHandlers() + 128
2  swift-frontend           0x0000000108bb9c08 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           0x0000000108b1aa30 llvm::install_out_of_memory_new_handler() + 0
7  swift-frontend           0x0000000104f8154c swift::LinearLifetimeChecker::ErrorBuilder::tryDumpErrorCounter() const + 0
8  swift-frontend           0x0000000104f80a14 swift::SILValueOwnershipChecker::checkValueWithoutLifetimeEndingUses(llvm::ArrayRef<swift::Operand*>) + 624
9  swift-frontend           0x0000000104f7f390 swift::SILValueOwnershipChecker::checkUses() + 248
10 swift-frontend           0x0000000104f7f0a0 swift::SILValueOwnershipChecker::check() + 212
11 swift-frontend           0x0000000104f8102c verifySILValueHelper(swift::SILFunction const*, swift::SILValue, swift::LinearLifetimeChecker::ErrorBuilder&, swift::DeadEndBlocks*, swift::GuaranteedPhiVerifier&) + 148
12 swift-frontend           0x0000000104f80f08 swift::SILValue::verifyOwnership(swift::DeadEndBlocks*) const + 196
13 swift-frontend           0x0000000104f9e530 (anonymous namespace)::SILVerifier::checkValueBaseOwnership(swift::ValueBase*) + 164
14 swift-frontend           0x0000000104fa07bc (anonymous namespace)::SILVerifier::visitSILInstruction(swift::SILInstruction*) + 5192
15 swift-frontend           0x0000000104f8dc90 swift::SILInstructionVisitor<(anonymous namespace)::SILVerifier, void>::visit(swift::SILInstruction*) + 13940
16 swift-frontend           0x0000000104f8a1b0 (anonymous namespace)::SILVerifier::visitSILBasicBlock(swift::SILBasicBlock*) + 1324
17 swift-frontend           0x0000000104f88b18 (anonymous namespace)::SILVerifier::visitSILFunction(swift::SILFunction*) + 8708
18 swift-frontend           0x0000000104f82adc swift::SILFunction::verify(bool) const + 76
19 swift-frontend           0x00000001048e4984 swift::autodiff::PullbackCloner::run() + 52
20 swift-frontend           0x0000000104900058 swift::autodiff::VJPCloner::Implementation::run() + 1368
21 swift-frontend           0x0000000104900644 swift::autodiff::VJPCloner::run() + 24
22 swift-frontend           0x0000000104a09b7c (anonymous namespace)::DifferentiationTransformer::canonicalizeDifferentiabilityWitness(swift::SILDifferentiabilityWitness*, swift::autodiff::DifferentiationInvoker, swift::IsSerialized_t) + 5328
23 swift-frontend           0x0000000104a07cc8 (anonymous namespace)::Differentiation::run() + 920
24 swift-frontend           0x0000000104a8f0b0 swift::SILPassManager::runModulePass(unsigned int) + 984
25 swift-frontend           0x0000000104a94d8c swift::SILPassManager::execute() + 624
26 swift-frontend           0x0000000104a8c0bc swift::SILPassManager::executePassPipelinePlan(swift::SILPassPipelinePlan const&) + 68
27 swift-frontend           0x0000000104a8c044 swift::ExecuteSILPipelineRequest::evaluate(swift::Evaluator&, swift::SILPipelineExecutionDescriptor) const + 68
28 swift-frontend           0x0000000104aaf5e8 swift::SimpleRequest<swift::ExecuteSILPipelineRequest, std::__1::tuple<> (swift::SILPipelineExecutionDescriptor), (swift::RequestFlags)1>::evaluateRequest(swift::ExecuteSILPipelineRequest const&, swift::Evaluator&) + 28
29 swift-frontend           0x0000000104a988e4 llvm::Expected<swift::ExecuteSILPipelineRequest::OutputType> swift::Evaluator::getResultUncached<swift::ExecuteSILPipelineRequest>(swift::ExecuteSILPipelineRequest const&) + 252
30 swift-frontend           0x0000000104a8c2b8 swift::executePassPipelinePlan(swift::SILModule*, swift::SILPassPipelinePlan const&, bool, swift::irgen::IRGenModule*) + 84
31 swift-frontend           0x0000000104a9c06c swift::runSILDiagnosticPasses(swift::SILModule&) + 92
32 swift-frontend           0x0000000104447f94 swift::CompilerInstance::performSILProcessing(swift::SILModule*) + 68
33 swift-frontend           0x00000001042de19c 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*) + 716
34 swift-frontend           0x00000001042dd92c swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 576
35 swift-frontend           0x00000001042ec63c withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) + 160
36 swift-frontend           0x00000001042df61c swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 3204
37 swift-frontend           0x0000000104135414 swift::mainEntry(int, char const**) + 3304
38 dyld                     0x0000000111acd088 start + 516

Expected behavior
The code should compile successfully.

Environment

  • Swift compiler version info: Any toolchain from 2022-04-23 to 2023-01-19 fails with this code.
  • Xcode version info: 13.3 (13E113).
  • Deployment target: M1, macOS 12.3.1.

Additional information
Commenting out the last two lines in func f and replacing them with a hard-coded return value will cause the compilation process to succeed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    AutoDiffSILGenArea → compiler: The SIL generation stagebugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselfcrashBug: A crash, i.e., an abnormal termination of softwareswift 5.9verifier

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions