Small code example crashes compiler only with -O. Xcode 10.2 regression?

I think the following program compiled fine prior to Xcode 10.2, but now (with Xcode 10.2) it crashes the compiler with optimizations (not without):

import simd

struct Curve {
    var p0, p1, p2, p3: float2
    var points: [float2] { return [p0, p1, p2, p3 ] }
    init(_ p0: float2, _ p3: float2) {
        (self.p0, self.p1, self.p2, self.p3) = (p0, p0, p3, p3)
    }
}

struct Polycurve {
    var points: [float2]
    init(_ points: [float2]) { self.points = points }
}

func test() {
    let c = Curve(float2(0, 0), float2(1, 1))
    let pc = Polycurve(c.points + [c.points[0]]) // <--- This crashes the compiler (compiling with -O).
    //let pc = Polycurve(c.points + [c.p0]) // <-- Note that this reformulation does not crash the compiler.
    print(pc)
}
test()

We first noticed this in our iOS application (within Xcode) and managed to reduce it to the above command line program.

Seems like it might have something to do with SE-0229 since replacing float2 with eg Int will not trigger the crash.


Stack dumps etc.
$ swiftc --version
Apple Swift version 5.0 (swiftlang-1001.0.69.5 clang-1001.0.46.3)
Target: x86_64-apple-darwin18.5.0

So, as previously stated, it compiles fine in debug builds (and release with incremental rather than whole module from within Xcode):

$ swiftc test.swift
$ ./test
Polycurve(points: [SIMD2<Float>(0.0, 0.0), SIMD2<Float>(0.0, 0.0), SIMD2<Float>(1.0, 1.0), SIMD2<Float>(1.0, 1.0), SIMD2<Float>(0.0, 0.0)])

But it crashes the compiler if using -O (or release mode with whole module rather than incremental within Xcode):

$ swiftc -O test.swift
Stack dump:
0.	Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c -primary-file test.swift -target x86_64-apple-darwin18.5.0 -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -O -color-diagnostics -module-name test -o /var/folders/50/br4kxvjd0t551h0fmtrzkwdw0000gn/T/test-ae77e8.o 
1.	While running pass #7084 SILFunctionTransform "DCE" on SILFunction "@$s4testAAyyF".
 for 'test()' (at test.swift:16:1)
0  swift                    0x000000010e63bee3 PrintStackTraceSignalHandler(void*) + 51
1  swift                    0x000000010e63b6bc SignalHandler(int) + 348
2  libsystem_platform.dylib 0x00007fff5b263b5d _sigtramp + 29
3  libsystem_platform.dylib 0x000000010fbcfe00 _sigtramp + 3029779136
4  swift                    0x000000010b309a00 (anonymous namespace)::DCE::markControllingTerminatorsLive(swift::SILBasicBlock*) + 816
5  swift                    0x000000010b3092e1 (anonymous namespace)::DCE::markValueLive(swift::SILNode*) + 417
6  swift                    0x000000010b306c2c (anonymous namespace)::DCE::run() + 2940
7  swift                    0x000000010b292823 swift::SILPassManager::execute() + 4627
8  swift                    0x000000010a4a0408 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 50264
9  swift                    0x000000010a4906de swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 6862
10 swift                    0x000000010a42e7be main + 1246
11 libdyld.dylib            0x00007fff5b07e3d5 start + 1
<unknown>:0: error: unable to execute command: Segmentation fault: 11
<unknown>:0: error: compile command failed due to signal 11 (use -v to see invocation)

And sometimes (maybe 5% of repeated swiftc -O test.swift) the crash will look like this instead:

$ swiftc -O test.swift
Stack dump:
0.	Program arguments: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c -primary-file test.swift -target x86_64-apple-darwin18.5.0 -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -O -color-diagnostics -module-name test -o /var/folders/50/br4kxvjd0t551h0fmtrzkwdw0000gn/T/test-d17efe.o 
1.	While running pass #7081 SILFunctionTransform "EarlyRedundantLoadElimination" on SILFunction "@$s4testAAyyF".
 for 'test()' (at test.swift:16:1)
0  swift                    0x000000010fd10ee3 PrintStackTraceSignalHandler(void*) + 51
1  swift                    0x000000010fd106bc SignalHandler(int) + 348
2  libsystem_platform.dylib 0x00007fff5b263b5d _sigtramp + 29
3  libsystem_platform.dylib 0x0000002000000008 _sigtramp + 2765735112
4  libsystem_c.dylib        0x00007fff5b1236a6 abort + 127
5  libsystem_malloc.dylib   0x00007fff5b231aef malloc_vreport + 545
6  libsystem_malloc.dylib   0x00007fff5b2318b0 malloc_report + 151
7  swift                    0x000000010cc28333 llvm::DenseMap<swift::Lowering::TypeConverter::CachingTypeKey, swift::Lowering::TypeLowering const*, llvm::DenseMapInfo<swift::Lowering::TypeConverter::CachingTypeKey>, llvm::detail::DenseMapPair<swift::Lowering::TypeConverter::CachingTypeKey, swift::Lowering::TypeLowering const*> >::grow(unsigned int) + 643
8  swift                    0x000000010cc28097 llvm::detail::DenseMapPair<swift::Lowering::TypeConverter::CachingTypeKey, swift::Lowering::TypeLowering const*>* llvm::DenseMapBase<llvm::DenseMap<swift::Lowering::TypeConverter::CachingTypeKey, swift::Lowering::TypeLowering const*, llvm::DenseMapInfo<swift::Lowering::TypeConverter::CachingTypeKey>, llvm::detail::DenseMapPair<swift::Lowering::TypeConverter::CachingTypeKey, swift::Lowering::TypeLowering const*> >, swift::Lowering::TypeConverter::CachingTypeKey, swift::Lowering::TypeLowering const*, llvm::DenseMapInfo<swift::Lowering::TypeConverter::CachingTypeKey>, llvm::detail::DenseMapPair<swift::Lowering::TypeConverter::CachingTypeKey, swift::Lowering::TypeLowering const*> >::InsertIntoBucketImpl<swift::Lowering::TypeConverter::CachingTypeKey>(swift::Lowering::TypeConverter::CachingTypeKey const&, swift::Lowering::TypeConverter::CachingTypeKey const&, llvm::detail::DenseMapPair<swift::Lowering::TypeConverter::CachingTypeKey, swift::Lowering::TypeLowering const*>*) + 103
9  swift                    0x000000010cc2b3e4 swift::Lowering::TypeConverter::getTypeLowering(swift::SILType) + 340
10 swift                    0x000000010c823b67 swift::TypeExpansionAnalysis::getTypeExpansion(swift::SILType, swift::SILModule*) + 199
11 swift                    0x000000010caec91d swift::LSValue::expand(swift::SILValue, swift::SILModule*, llvm::SmallVector<swift::LSValue, 8u>&, swift::TypeExpansionAnalysis*) + 45
12 swift                    0x000000010ca06b87 (anonymous namespace)::BlockState::processStoreInst((anonymous namespace)::RLEContext&, swift::StoreInst*, RLEKind) + 2407
13 swift                    0x000000010ca0403b (anonymous namespace)::RedundantLoadElimination::run() + 6075
14 swift                    0x000000010c967823 swift::SILPassManager::execute() + 4627
15 swift                    0x000000010bb75408 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 50264
16 swift                    0x000000010bb656de swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 6862
17 swift                    0x000000010bb037be main + 1246
18 libdyld.dylib            0x00007fff5b07e3d5 start + 1
<unknown>:0: error: unable to execute command: Abort trap: 6
<unknown>:0: error: compile command failed due to signal 6 (use -v to see invocation)

I have only tested this with the default toolchain of Xcode 10.2 (no recent snapshot, not Xcode 10.1).


Filed SR-10343


Out of curiosity: How come the stack dump is not always the same?

This looks like a heap corruption in the compiler to me, I didn't do a deep analysis here at all, so take with a grain of salt, however: If the trap comes out of malloc_vreport, that's probably a sign that something was broken enough with the heap that malloc detected it and called malloc_vreport to output some debugging information. The exact shape of the heap is however non-deterministic, so in other cases malloc might not catch the corruption (or there might be none) and the crash happens elsewhere.

2 Likes
Terms of Service

Privacy Policy

Cookie Policy