[Help needed] IRGenDebugInfo crash

Hi IRGen experts,

We recently ran into a IRGenDebugInfo crash (TF-597) on the tensorflow branch during stdlib compilation:

Assertion failed: (OffsetInBits + SizeInBits <= getSizeInBits(Var) && "pars > totum"), function emitVariableDeclaration, file /Users/danielzheng/swift-build/swift/lib/IRGen/IRGenDebugInfo.cpp, line 2212.
Stack dump:
0.	Program arguments: ./build/Xcode-ReleaseAssert+swift-DebugAssert/swift-macosx-x86_64/Debug/bin/swift -frontend -c -filelist /var/folders/m_/6f7q8zfs3n9fr0c_4gy8840m00hc_q/T/sources-80e037 -supplementary-output-file-map /var/folders/m_/6f7q8zfs3n9fr0c_4gy8840m00hc_q/T/supplementaryOutputs-68e761 -disable-objc-attr-requires-foundation-module -target x86_64-apple-macosx10.9 -enable-objc-interop -sdk /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -I /Users/danielzheng/swift-build/build/Ninja-RelWithDebInfoAssert+swift-DebugAssert/swift-macosx-x86_64/./lib/swift/macosx -F /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/../../../Developer/Library/Frameworks -warn-swift3-objc-inference-complete -warn-implicit-overrides -enable-library-evolution -g -module-cache-path /Users/danielzheng/swift-build/build/Ninja-RelWithDebInfoAssert+swift-DebugAssert/swift-macosx-x86_64/./module-cache -module-link-name swiftCore -nostdimport -parse-stdlib -resource-dir /Users/danielzheng/swift-build/build/Ninja-RelWithDebInfoAssert+swift-DebugAssert/swift-macosx-x86_64/./lib/swift -swift-version 5 -O -D INTERNAL_CHECKS_ENABLED -D SWIFT_ENABLE_RUNTIME_FUNCTION_COUNTERS -enable-resilience -enforce-exclusivity=unchecked -group-info-path /Users/danielzheng/swift-build/swift/stdlib/public/core/GroupInfo.json -verify-syntax-tree -enable-anonymous-context-mangled-names -Xllvm -sil-inline-generics -Xllvm -sil-partial-specialization -Xcc -DswiftCore_EXPORTS -parse-as-library -module-name Swift -o /Users/danielzheng/swift-build/build/Ninja-RelWithDebInfoAssert+swift-DebugAssert/swift-macosx-x86_64/stdlib/public/core/OSX/x86_64/Swift.o -runtime-compatibility-version none
1.	Swift version 5.1-dev (LLVM e56fafcd29, Swift 07043f52ff)
2.	Contents of /var/folders/m_/6f7q8zfs3n9fr0c_4gy8840m00hc_q/T/sources-80e037:
3.	While emitting IR SIL function "@$ss8pullback2at2in13TangentVectorQzADQy_cx_q_xXEts14DifferentiableRzsAGR_r0_lF".
 for 'pullback(at:in:)' (at /Users/danielzheng/swift-build/swift/stdlib/public/core/AutoDiff.swift:366:8)
namespace)::IRGenDebugInfoImpl::emitVariableDeclaration(swift::irgen::IRBuilder&, llvm::ArrayRef<llvm::Value*>, swift::irgen::DebugTypeInfo, swift::SILDebugScope const*, swift::ValueDecl*, llvm::StringRef, unsigned int, swift::irgen::IndirectionKind, swift::irgen::ArtificialKind) + 2664

The crash appeared after merging from master to tensorflow sometime in June: either after syncing to swift-DEVELOPMENT-SNAPSHOT-2019-06-06-a or swift-DEVELOPMENT-SNAPSHOT-2019-06-13-a.

The assertion failure happens here in IRGenDebugInfoImpl::emitVariableDeclaration. It's related to the @differentiable function typed argument of pullback(at:in:):

@inlinable
public func pullback<T, R>(
  at x: T, in f: @differentiable (T) -> R
) -> (R.TangentVector) -> T.TangentVector {
  return Builtin.autodiffApply_vjp(f, x).1
}

@differentiable function types only exist on the tensorflow branch, but we haven't encountered any IRGenDebugInfo crashes until very recently. Looking at the history of lib/IRGen and lib/IRGen/IRGenDebugInfo.cpp, it's not clear what changes led to this crash.

Does anyone have any ideas for debugging this? Any help would be appreciated!

I added some debug print statements for more info about the assertion failure:
Assertion 'OffsetInBits + SizeInBits <= getSizeInBits(Var) && "pars > totum" failed.

Piece: '', total # pieces: 6
i8*

IRGenDebugInfo crash for VarDecl 'f', ArgNo: 2
(parameter "f" apiName=in type='@differentiable (T) -> R' interface type='@differentiable (T) -> R')
OffsetInBits: 128
SizeInBits: 64
getSizeInBits(Var): 128

Debug type:
[Size 48 Alignment 8] (sil_function_type type=@differentiable @noescape @callee_guaranteed (@in_guaranteed T) -> @out R)
StorageType=<{ %swift.noescape.function, %swift.noescape.function, %swift.noescape.function }>

Debug info type:
<0x2379a7f8> = !DICompositeType(tag: DW_TAG_structure_type, name: "$sxq_Ignr_D", file: <0x2eb93490>, size: 128, elements: <0x33d53990>, runtimeLang: DW_LANG_Swift, identifier: "$sxq_Ignr_D")
swift: /home/danielzheng/swift-merge/swift/lib/IRGen/IRGenDebugInfo.cpp:2198: void (anonymous namespace)::IRGenDebugInfoImpl::emitVariableDeclaration(swift::irgen::IRBuilder &, ArrayRef<llvm::Value *>, swift::irgen::DebugTypeInfo, const swift::SILDebugScope *, swift::ValueDecl *, llvm::StringRef, unsigned int, swift::irgen::IndirectionKind, swift::irgen::ArtificialKind): Assertion `OffsetInBits + SizeInBits <= getSizeInBits(Var) && "pars > totum"' failed.

Patch:

diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp
index c643728589..d593bd40be 100644
--- a/lib/IRGen/IRGenDebugInfo.cpp
+++ b/lib/IRGen/IRGenDebugInfo.cpp
@@ -2177,6 +2177,21 @@ void IRGenDebugInfoImpl::emitVariableDeclaration(
       if (!AlignInBits)
         AlignInBits = SizeOfByte;

+      if (!(OffsetInBits + SizeInBits <= getSizeInBits(Var))) {
+        llvm::errs() << "Piece: '" << Piece->getName() << "', total # pieces: " << Storage.size() << "\n";
+        Piece->getType()->dump();
+        llvm::errs() << "IRGenDebugInfo crash for VarDecl '" << Name << "', ArgNo: " << ArgNo << "\n";
+        VarDecl->dump();
+        llvm::errs() << "OffsetInBits: " << OffsetInBits << "\n";
+        llvm::errs() << "SizeInBits: " << SizeInBits << "\n";
+        llvm::errs() << "getSizeInBits(Var): " << getSizeInBits(Var) << "\n";
+
+        llvm::errs() << "\nDebug type:\n";
+        DbgTy.dump();
+        llvm::errs() << "\nDebugInfo type:\n";
+        DITy->dump();
+      }
+
       // Sanity checks.
       assert(SizeInBits && "zero-sized piece");
       assert(SizeInBits < getSizeInBits(Var) && "piece covers entire var");

It seems like the debug info is not matching up with the layout. The getSizeInBits(Var) is indicating that the size is 128-bits (16-bytes). The fragment being looked at is offset by 16-bytes from the beginning of the object, so your object is either sized incorrect or the fragment is sized incorrectly. Is this happening in a debug build or a release build? It could be that some optimization is failing to update the DebugInfo.

Thank you for the info!

This happens in a --release-debuginfo build but not a --debug build, so you may be onto something about "optimizations failing to update the DebugInfo".

Do you/anyone have any tips for debugging this? Could you please point to related code, if you're familiar?