Since upgrading to Xcode 16.3 / Swift 6.1, my codebase no longer compiles when optimizations are on (-O or -Osize).
Apple Swift version 6.1 (swiftlang-6.1.0.110.21 clang-1700.0.13.3)
Compiling with effective version 5.10
While evaluating request ExecuteSILPipelineRequest(Run pipelines { PrepareOptimizationPasses, EarlyModulePasses, HighLevel,Function+EarlyLoopOpt, HighLevel,Module+StackPromote, MidLevel,Function, ClosureSpecialize, LowLevel,Function, LateLoopOpt, SIL Debug Info Generator } on SIL for FxCore)
While running pass #79927 SILFunctionTransform "ComputeSideEffects" on SILFunction "@$s6FxCore14UpscalerPlugInC7executeyyKF".
Submitting an entire codebase is not an option, so I would love to get to the point where I know exactly what it is about my sources that is causing the crash and submit a reproducible case (https://github.com/swiftlang/swift/issues/80566). While the above error points the finger at a specific function in a specific file, commenting that out or even removing the file from the project simply means the crash happens on the next file in line for compilation.
I tried blanket-prepending @available(*, unavailable) to the functions mentioned in the crash, but this makes no difference: the compiler still seems to invoke "ComputeSideEffects" on those annotated functions. Are there any techniques you have come to rely on, when working out compiler crashes? "Secret" frontend options that tweak the optimization phase and shed light on what’s going on?
Try annotating the offending functions with @_optimize(none).
There’s a certain art to reducing compiler crash test cases.
You can either delete code until you can’t delete anything else without the problem going away, but this will take a while with a large module.
Alternatively you start with your original function in a source file and stub out enough of the surrounding declarations to get it to compile, for example by giving them types and leaving the implementation as fatalError().
This can be a bit trickier with optimizer bugs that rely on inlining having taken place though, since now your test case may need to fill out multiple function bodies, but generally you can reproduce almost any compiler bug with a 100 line test case at most (and usually much less than that). Occasionally you need multiple source files or modules to trigger an issue too.
Another trick is to try an asserts toolchain. An assertion failure is more actionable than a random crash from UB (which often is what you get if a failed assertion is skipped). Sometimes this reveals that the real problem is in an earlier stage of the compiler, for example, a noasserts build might crash in the SILOptimizer if SILGen constructed something nonsensical because a type checking invariant was violated.
Thank you for the quick tip. Unfortunately no matter how many @_optimize(none) statements I kept adding to the sources, I was never able to avoid the crashes. The goalpost would keep moving, from a function to a block within a function, then after randomly decorating any invoked functions within the block, to something other than "ComputeSideEffects". Not a fun process.
I'm taking the shortcut for now and downgrading to Xcode 16.2, then praying the next release doesn't have the same bug. Comments made to my issue in the bug tracker suggest this may have already been fixed in more recent builds.