swift: [5.8] sil crash with optimizations enabled

With this code:

import UIKit

final class LottieAnimation {}
protocol RootAnimationLayer: CALayer {}

class LottieAnimationView: UIView {
  var animationLayer: RootAnimationLayer?

  func layoutAnimation() {
    guard let animationLayer else { return }

    animationLayer.removeAnimation(forKey: "")
    print(animationLayer.presentation())
  }
}

If you build with the 12-10-22 development snapshot with:

TOOLCHAINS=org.swift.57202212101a xcrun swiftc -O -target arm64-apple-ios13.0 -sdk `xcrun --show-sdk-path --sdk iphoneos` foo.swift

You get this crash:

SIL verification failed: switch_enum destination bbarg must match case arg type: eltArgTy == bbArgTy
Verifying instruction:
     %39 = unchecked_ref_cast %38 : $Optional<CALayer> to $Optional<@opened("5C3CD7F8-7A91-11ED-9801-1E92632656FD", any RootAnimationLayer) Self> // type-defs: %7; user: %40
->   switch_enum %39 : $Optional<@opened("5C3CD7F8-7A91-11ED-9801-1E92632656FD", any RootAnimationLayer) Self>, case #Optional.some!enumelt: bb2, case #Optional.none!enumelt: bb4 // id: %40
In function:
// LottieAnimationView.layoutAnimation()
sil hidden @$s3foo19LottieAnimationViewC06layoutC0yyF : $@convention(method) (@guaranteed LottieAnimationView) -> () {
[%0: read c*.v**, write c*.v**, copy c*.v**, destroy c*.v**]
[global: read,write,copy,destroy,allocate,deinit_barrier]
// %0 "self"                                      // users: %3, %2, %1
bb0(%0 : $LottieAnimationView):
  debug_value %0 : $LottieAnimationView, let, name "self", argno 1, implicit // id: %1
  %2 = class_method %0 : $LottieAnimationView, #LottieAnimationView.animationLayer!getter : (LottieAnimationView) -> () -> (any RootAnimationLayer)?, $@convention(method) (@guaranteed LottieAnimationView) -> @owned Optional<any RootAnimationLayer> // user: %3
  %3 = apply %2(%0) : $@convention(method) (@guaranteed LottieAnimationView) -> @owned Optional<any RootAnimationLayer> // users: %66, %4
  switch_enum %3 : $Optional<any RootAnimationLayer>, case #Optional.some!enumelt: bb1, case #Optional.none!enumelt: bb5 // id: %4

// %5                                             // users: %6, %7
bb1(%5 : $any RootAnimationLayer):                // Preds: bb0
  debug_value %5 : $any RootAnimationLayer, let, name "animationLayer" // id: %6
  %7 = open_existential_ref %5 : $any RootAnimationLayer to $@opened("5C3CD7F8-7A91-11ED-9801-1E92632656FD", any RootAnimationLayer) Self // users: %42, %39, %8
  %8 = upcast %7 : $@opened("5C3CD7F8-7A91-11ED-9801-1E92632656FD", any RootAnimationLayer) Self to $CALayer // users: %37, %38, %22, %21
  %9 = integer_literal $Builtin.Int64, 0          // user: %10
  %10 = struct $UInt64 (%9 : $Builtin.Int64)      // user: %16
  %11 = integer_literal $Builtin.Int64, -2305843009213693952 // user: %12
  %12 = value_to_bridge_object %11 : $Builtin.Int64 // user: %13
  %13 = unchecked_trivial_bit_cast %12 : $Builtin.BridgeObject to $UInt64 // user: %14
  %14 = struct_extract %13 : $UInt64, #UInt64._value // user: %15
  %15 = value_to_bridge_object %14 : $Builtin.Int64 // user: %16
  %16 = struct $_StringObject (%10 : $UInt64, %15 : $Builtin.BridgeObject) // user: %17
  %17 = struct $_StringGuts (%16 : $_StringObject) // user: %18
  %18 = struct $String (%17 : $_StringGuts)       // user: %20
  // function_ref String._bridgeToObjectiveC()
  %19 = function_ref @$sSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF : $@convention(method) (@guaranteed String) -> @owned NSString // user: %20
  %20 = apply %19(%18) : $@convention(method) (@guaranteed String) -> @owned NSString // users: %23, %22
  %21 = objc_method %8 : $CALayer, #CALayer.removeAnimation!foreign : (CALayer) -> (String) -> (), $@convention(objc_method) (NSString, CALayer) -> () // user: %22
  %22 = apply %21(%20, %8) : $@convention(objc_method) (NSString, CALayer) -> ()
  strong_release %20 : $NSString                  // id: %23
  %24 = integer_literal $Builtin.Word, 1          // user: %27
  %25 = integer_literal $Builtin.Int64, 1         // user: %26
  %26 = struct $Int (%25 : $Builtin.Int64)        // user: %31
  %27 = alloc_ref [tail_elems $Any * %24 : $Builtin.Word] $_ContiguousArrayStorage<Any> // users: %46, %28
  %28 = upcast %27 : $_ContiguousArrayStorage<Any> to $__ContiguousArrayStorageBase // users: %35, %33
  %29 = integer_literal $Builtin.Int64, 2         // user: %30
  %30 = struct $UInt (%29 : $Builtin.Int64)       // user: %31
  %31 = struct $_SwiftArrayBodyStorage (%26 : $Int, %30 : $UInt) // user: %32
  %32 = struct $_ArrayBody (%31 : $_SwiftArrayBodyStorage) // user: %34
  %33 = ref_element_addr %28 : $__ContiguousArrayStorageBase, #__ContiguousArrayStorageBase.countAndCapacity // user: %34
  store %32 to %33 : $*_ArrayBody                 // id: %34
  %35 = ref_tail_addr %28 : $__ContiguousArrayStorageBase, $Any // user: %36
  %36 = init_existential_addr %35 : $*Any, $Optional<any RootAnimationLayer> // users: %69, %44
  %37 = objc_method %8 : $CALayer, #CALayer.presentation!foreign : (CALayer) -> () -> @dynamic_self CALayer?, $@convention(objc_method) (CALayer) -> @autoreleased Optional<CALayer> // user: %38
  %38 = apply %37(%8) : $@convention(objc_method) (CALayer) -> @autoreleased Optional<CALayer> // user: %39
  %39 = unchecked_ref_cast %38 : $Optional<CALayer> to $Optional<@opened("5C3CD7F8-7A91-11ED-9801-1E92632656FD", any RootAnimationLayer) Self> // type-defs: %7; user: %40
  switch_enum %39 : $Optional<@opened("5C3CD7F8-7A91-11ED-9801-1E92632656FD", any RootAnimationLayer) Self>, case #Optional.some!enumelt: bb2, case #Optional.none!enumelt: bb4 // id: %40

// %41                                            // user: %42
bb2(%41 : $@opened("5C3CE4AA-7A91-11ED-9801-1E92632656FD", any RootAnimationLayer) Self): // Preds: bb1
  %42 = init_existential_ref %41 : $@opened("5C3CE4AA-7A91-11ED-9801-1E92632656FD", any RootAnimationLayer) Self : $@opened("5C3CD7F8-7A91-11ED-9801-1E92632656FD", any RootAnimationLayer) Self, $any RootAnimationLayer // type-defs: %7; user: %43
  %43 = enum $Optional<any RootAnimationLayer>, #Optional.some!enumelt, %42 : $any RootAnimationLayer // user: %44
  store %43 to %36 : $*Optional<any RootAnimationLayer> // id: %44
  br bb3                                          // id: %45

bb3:                                              // Preds: bb4 bb2
  %46 = end_cow_mutation %27 : $_ContiguousArrayStorage<Any> // users: %65, %47
  %47 = unchecked_ref_cast %46 : $_ContiguousArrayStorage<Any> to $Builtin.BridgeObject // user: %48
  %48 = struct $_BridgeStorage<__ContiguousArrayStorageBase> (%47 : $Builtin.BridgeObject) // user: %49
  %49 = struct $_ArrayBuffer<Any> (%48 : $_BridgeStorage<__ContiguousArrayStorageBase>) // user: %50
  %50 = struct $Array<Any> (%49 : $_ArrayBuffer<Any>) // user: %64
  %51 = integer_literal $Builtin.Int64, 32        // user: %52
  %52 = struct $UInt64 (%51 : $Builtin.Int64)     // user: %55
  %53 = integer_literal $Builtin.Int64, -2233785415175766016 // user: %54
  %54 = value_to_bridge_object %53 : $Builtin.Int64 // users: %60, %55
  %55 = struct $_StringObject (%52 : $UInt64, %54 : $Builtin.BridgeObject) // user: %56
  %56 = struct $_StringGuts (%55 : $_StringObject) // user: %57
  %57 = struct $String (%56 : $_StringGuts)       // user: %64
  %58 = integer_literal $Builtin.Int64, 10        // user: %59
  %59 = struct $UInt64 (%58 : $Builtin.Int64)     // user: %60
  %60 = struct $_StringObject (%59 : $UInt64, %54 : $Builtin.BridgeObject) // user: %61
  %61 = struct $_StringGuts (%60 : $_StringObject) // user: %62
  %62 = struct $String (%61 : $_StringGuts)       // user: %64
  // function_ref print(_:separator:terminator:)
  %63 = function_ref @$ss5print_9separator10terminatoryypd_S2StF : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> () // user: %64
  %64 = apply %63(%50, %57, %62) : $@convention(thin) (@guaranteed Array<Any>, @guaranteed String, @guaranteed String) -> ()
  strong_release %46 : $_ContiguousArrayStorage<Any> // id: %65
  release_value %3 : $Optional<any RootAnimationLayer> // id: %66
  br bb6                                          // id: %67

bb4:                                              // Preds: bb1
  %68 = enum $Optional<any RootAnimationLayer>, #Optional.none!enumelt // user: %69
  store %68 to %36 : $*Optional<any RootAnimationLayer> // id: %69
  br bb3                                          // id: %70

bb5:                                              // Preds: bb0
  br bb6                                          // id: %71

bb6:                                              // Preds: bb3 bb5
  %72 = tuple ()                                  // user: %73
  return %72 : $()                                // id: %73
} // end sil function '$s3foo19LottieAnimationViewC06layoutC0yyF'

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-2022-12-10-a.xctoolchain/usr/bin/swift-frontend -frontend -c -primary-file foo.swift -target arm64-apple-ios13.0 -Xllvm -aarch64-use-tbi -enable-objc-interop -sdk /Applications/Xcode-14.1.0-RC2.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.1.sdk -color-diagnostics -O -new-driver-path /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2022-12-10-a.xctoolchain/usr/bin/swift-driver -empty-abi-descriptor -resource-dir /Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2022-12-10-a.xctoolchain/usr/lib/swift -module-name foo -target-sdk-version 16.1 -target-sdk-name iphoneos16.1 -enable-default-cmo -o /var/folders/gj/wf3swl0x215b2sq1qy84kzkm0000gn/T/TemporaryDirectory.j1R26O/foo-1.o
1.      Apple Swift version 5.8-dev (LLVM 767c0998bcfdab1, Swift 1f3397ac116fada)
2.      Compiling with the current language version
3.      While verifying SIL function "@$s3foo19LottieAnimationViewC06layoutC0yyF".
 for 'layoutAnimation()' (at foo.swift:9:3)
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           0x0000000106f8b338 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x0000000106f8a5bc llvm::sys::RunSignalHandlers() + 128
2  swift-frontend           0x0000000106f8b978 SignalHandler(int) + 304
3  libsystem_platform.dylib 0x00000001a406c2a4 _sigtramp + 56
4  libsystem_pthread.dylib  0x00000001a403dcec pthread_kill + 288
5  libsystem_c.dylib        0x00000001a3f772c8 abort + 180
6  swift-frontend           0x000000010337d220 (anonymous namespace)::SILVerifier::_require(bool, llvm::Twine const&, std::__1::function<void ()> const&) + 1456
7  swift-frontend           0x000000010339db70 (anonymous namespace)::SILVerifier::checkSwitchEnumInst(swift::SwitchEnumInst*)::'lambda'(swift::EnumElementDecl*, swift::SILBasicBlock*)::operator()(swift::EnumElementDecl*, swift::SILBasicBlock*) const + 676
8  swift-frontend           0x0000000103384370 swift::SILInstructionVisitor<(anonymous namespace)::SILVerifier, void>::visit(swift::SILInstruction*) + 11832
9  swift-frontend           0x00000001033810b8 (anonymous namespace)::SILVerifier::visitSILBasicBlock(swift::SILBasicBlock*) + 1336
10 swift-frontend           0x000000010337fab0 (anonymous namespace)::SILVerifier::visitSILFunction(swift::SILFunction*) + 8748
11 swift-frontend           0x000000010337c700 swift::SILModule::verify() const + 216
12 swift-frontend           0x000000010284bd40 swift::CompilerInstance::performSILProcessing(swift::SILModule*) + 552
13 swift-frontend           0x00000001026e6d9c 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
14 swift-frontend           0x00000001026e6528 swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 576
15 swift-frontend           0x00000001026f512c withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) + 160
16 swift-frontend           0x00000001026e821c swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 3204
17 swift-frontend           0x000000010255b5a4 swift::mainEntry(int, char const**) + 3288
18 dyld                     0x00000001a3d13e50 start + 2544

The real version of this was built from https://github.com/airbnb/lottie-ios/commit/9ce485d7b519a275628adb3667b483d5660524ff when building the Lottie framework for iOS in release mode

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 15

Most upvoted comments

btw, shouldn’t there be a label added for Swift 5.8?

Are you confident that you’re facing the same issue? Try extracting the lines that cause the crash into a separate function. This workaround is simply an observation, not much reasoning behind it.

@thekief I haven’t seen or heard of any progress on this yet. In the meantime, you can apparently dodge the crash by extracting the print into a function:

final class LottieAnimation {}
protocol RootAnimationLayer: CALayer {}

extension RootAnimationLayer {
  func printPresentation() {
    print(self.presentation())
  }
}

class LottieAnimationView: UIView {
  var animationLayer: RootAnimationLayer?

  func layoutAnimation() {
    guard let animationLayer else { return }

    animationLayer.removeAnimation(forKey: "")
    animationLayer.printPresentation()
  }
}

Or just build the debug variant; You don’t need this print in production, do you?