Skip to content

Assert failure/crash in LoadableByAddress pass in getAddressForValue when building FoundationEssentials #78954

Open
@3405691582

Description

@3405691582

Description

When building FoundationEssentials with --release --skip-early-swift-driver --skip-early-swiftsyntax (and #77815), the frontend crashes or asserts with swift-frontend: ~/src/swift/swift/lib/IRGen/LoadableByAddress.cpp:3860: SILValue (anonymous namespace)::AddressAssignment::getAddressForValue(SILValue): Assertion it != valueToAddressMap.end()' failed.`

The workaround listed in #71744 (comment) still works (i.e., add -Xfrontend -disable-large-loadable-types-reg2mem to the target_compile_options in swift-foundation/Sources/FoundationEssentials/CMakeLists.txt). This only seems to reliably trip with Release builds; using Debug or RelWithDebInfo is also a workaround.

(Source paths lightly redacted.)

Reproduction

Unfortunately, I haven't identified a very small reproducing case. I know this is a nonstandard configuration but I don't think this means the underlying issue can or should be necessarily fully discounted, especially since this looks very closely related to #71744 and the resolution in #72617.

This can be reproduced on Linux by applying #77815 at HEAD as well as the following.

diff --git a/lib/AST/ASTScope.cpp b/lib/AST/ASTScope.cpp
index e8248ba9082..f1d4c13901e 100644
--- a/lib/AST/ASTScope.cpp
+++ b/lib/AST/ASTScope.cpp
@@ -148,6 +148,7 @@ void ASTScope::unqualifiedLookup(
   if (auto *s = SF->getASTContext().Stats)
     ++s->getFrontendCounters().NumASTScopeLookups;
 
+#if SWIFT_BUILD_SWIFT_SYNTAX
   // Perform validation of SwiftLexicalLookup if option
   // Feature::UnqualifiedLookupValidation is enabled and lookup was not
   // performed in a macro.
@@ -171,6 +172,9 @@ void ASTScope::unqualifiedLookup(
   } else {
     ASTScopeImpl::unqualifiedLookup(SF, loc, consumer);
   }
+#else
+    ASTScopeImpl::unqualifiedLookup(SF, loc, consumer);
+#endif
 }
 
 llvm::SmallVector<LabeledStmt *, 4> ASTScope::lookupLabeledStmts(
diff --git a/stdlib/public/core/SwiftifyImport.swift b/stdlib/public/core/SwiftifyImport.swift
index 3466d594996..7cf5a807fdd 100644
--- a/stdlib/public/core/SwiftifyImport.swift
+++ b/stdlib/public/core/SwiftifyImport.swift
@@ -57,6 +57,8 @@ public enum _SwiftifyInfo {
 ///
 /// Parameter paramInfo: information about how the function uses the pointer passed to it. The
 /// safety of the generated wrapper function depends on this info being extensive and accurate.
+#if hasFeature(Macros)
 @attached(peer, names: overloaded)
 public macro _SwiftifyImport(_ paramInfo: _SwiftifyInfo..., typeMappings: [String: String] = [:]) =
     #externalMacro(module: "SwiftMacros", type: "SwiftifyImportMacro")
+#endif

Then build:

./utils/build-script \
    --release \
    --build-subdir=bug \
    --skip-early-swift-driver \
    --skip-early-swiftsyntax \
    --foundation --xctest \
    --enable-experimental-string-processing \
    --extra-cmake-options="\
        -DSWIFT_ENABLE_SYNCHRONIZATION=ON,\
        -DSWIFT_ENABLE_EXPERIMENTAL_STRING_PROCESSING=ON,\
        -DSWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY=ON,"

Stack dump

Stack dump:
0.      Program arguments: ~/src/swift/build/bug/swift-linux-x86_64/bin/swift-frontend -frontend -c -filelist /tmp/sources-c88532 -supplementary-output-file-map /tmp/supplementaryOutputs-e65640 -target x86_64-unknown-linux-gnu -disable-objc-interop -I ~/src/swift/build/bug/foundation-linux-x86_64/swift -I ~/src/swift/swift-foundation/Sources/_FoundationCShims/include -module-cache-path ~/src/swift/build/bug/foundation-linux-x86_64/module-cache -module-link-name FoundationEssentials -package-name SwiftFoundation -O -D FoundationEssentials_EXPORTS -Xcc -D_GNU_SOURCE -enable-experimental-feature VariadicGenerics -enable-experimental-feature AccessLevelOnImport -enable-experimental-feature StrictConcurrency -enable-upcoming-feature InferSendableFromCaptures -enable-experimental-feature "AvailabilityMacro=FoundationPreview 0.1:macOS 13.3, iOS 16.4, tvOS 16.4, watchOS 9.4" -enable-experimental-feature "AvailabilityMacro=FoundationPredicate 0.1:macOS 14, iOS 17, tvOS 17, watchOS 10" -enable-experimental-feature "AvailabilityMacro=FoundationPredicateRegex 0.1:macOS 15, iOS 18, tvOS 18, watchOS 11" -enable-experimental-feature "AvailabilityMacro=FoundationPreview 0.2:macOS 13.3, iOS 16.4, tvOS 16.4, watchOS 9.4" -enable-experimental-feature "AvailabilityMacro=FoundationPredicate 0.2:macOS 14, iOS 17, tvOS 17, watchOS 10" -enable-experimental-feature "AvailabilityMacro=FoundationPredicateRegex 0.2:macOS 15, iOS 18, tvOS 18, watchOS 11" -enable-experimental-feature "AvailabilityMacro=FoundationPreview 0.3:macOS 13.3, iOS 16.4, tvOS 16.4, watchOS 9.4" -enable-experimental-feature "AvailabilityMacro=FoundationPredicate 0.3:macOS 14, iOS 17, tvOS 17, watchOS 10" -enable-experimental-feature "AvailabilityMacro=FoundationPredicateRegex 0.3:macOS 15, iOS 18, tvOS 18, watchOS 11" -enable-experimental-feature "AvailabilityMacro=FoundationPreview 0.4:macOS 13.3, iOS 16.4, tvOS 16.4, watchOS 9.4" -enable-experimental-feature "AvailabilityMacro=FoundationPredicate 0.4:macOS 14, iOS 17, tvOS 17, watchOS 10" -enable-experimental-feature "AvailabilityMacro=FoundationPredicateRegex 0.4:macOS 15, iOS 18, tvOS 18, watchOS 11" -enable-experimental-feature "AvailabilityMacro=FoundationPreview 6.0.2:macOS 13.3, iOS 16.4, tvOS 16.4, watchOS 9.4" -enable-experimental-feature "AvailabilityMacro=FoundationPredicate 6.0.2:macOS 14, iOS 17, tvOS 17, watchOS 10" -enable-experimental-feature "AvailabilityMacro=FoundationPredicateRegex 6.0.2:macOS 15, iOS 18, tvOS 18, watchOS 11" -enable-experimental-feature "AvailabilityMacro=FoundationPreview 6.1:macOS 13.3, iOS 16.4, tvOS 16.4, watchOS 9.4" -enable-experimental-feature "AvailabilityMacro=FoundationPredicate 6.1:macOS 14, iOS 17, tvOS 17, watchOS 10" -enable-experimental-feature "AvailabilityMacro=FoundationPredicateRegex 6.1:macOS 15, iOS 18, tvOS 18, watchOS 11" -enable-experimental-feature "AvailabilityMacro=FoundationPreview 6.2:macOS 13.3, iOS 16.4, tvOS 16.4, watchOS 9.4" -enable-experimental-feature "AvailabilityMacro=FoundationPredicate 6.2:macOS 14, iOS 17, tvOS 17, watchOS 10" -enable-experimental-feature "AvailabilityMacro=FoundationPredicateRegex 6.2:macOS 15, iOS 18, tvOS 18, watchOS 11" -plugin-path ~/src/swift/build/bug/foundation_macros-linux-x86_64/lib -in-process-plugin-server-path ~/src/swift/build/bug/swift-linux-x86_64/lib/swift/host/libSwiftInProcPluginServer.so -plugin-path ~/src/swift/build/bug/swift-linux-x86_64/lib/swift/host/plugins -plugin-path ~/src/swift/build/bug/swift-linux-x86_64/local/lib/swift/host/plugins -Xcc -fmodule-map-file=~/src/swift/swift-foundation/Sources/_FoundationCShims/include/module.modulemap -parse-as-library -module-name FoundationEssentials -num-threads 128 -output-filelist /tmp/outputs-04d836
1.      Swift version 6.2-dev (LLVM d36699c23f1ac57, Swift b73b90fc6c5a234)
2.      Compiling with effective version 5.10
3.      While evaluating request ExecuteSILPipelineRequest(Run pipelines { IRGen Preparation } on SIL for FoundationEssentials)
4.      While running pass #11184 SILModuleTransform "LoadableByAddress".

Expected behavior

Library successfully created.

Environment

Linux/x86_64 with #77815 and above diff to ensure successful compilation, Release builds.
Also triggers on OpenBSD/arm64, same conditions.

Additional information

Backtrace fragment (from Linux).

#6  0x00005555566f8d29 in (anonymous namespace)::AddressAssignment::getAddressForValue(swift::SILValue) ()
#7  0x00005555566f02e1 in (anonymous namespace)::AssignAddressToDef::rewriteValue() ()
#8  0x00005555566d2435 in runPeepholesAndReg2Mem(swift::SILPassManager*, swift::SILModule*, swift::irgen::IRGenModule*) ()
#9  0x00005555566d01a3 in (anonymous namespace)::LoadableByAddress::run() ()

If I rebuild just LoadableByAddress.cpp with debug info enabled, then we get a bit more information. gdb session fragment:

(gdb) bt
...
#6  0x00005555566f8d29 in (anonymous namespace)::AddressAssignment::getAddressForValue (this=0x7fffffff5280, v=...)
    at ~/src/swift/swift/lib/IRGen/LoadableByAddress.cpp:3860
#7  0x00005555566f02e1 in (anonymous namespace)::AssignAddressToDef::visitUncheckedBitwiseCastInst (this=0x7fffffff5028, bc=0x55558b6af5e0)
    at ~/src/swift/swift/lib/IRGen/LoadableByAddress.cpp:4205
#8  swift::SILInstructionVisitor<(anonymous namespace)::AssignAddressToDef, void>::visit (this=0x7fffffff5028, inst=0x55558b6af5e0)
    at ~/src/swift/swift/include/swift/SIL/SILNodes.def:392
#9  (anonymous namespace)::AssignAddressToDef::rewriteValue (
    this=this@entry=0x7fffffff5028)
    at ~/src/swift/swift/lib/IRGen/LoadableByAddress.cpp:4216
#10 0x00005555566d2435 in (anonymous namespace)::AddressAssignment::assign (
    this=0x7fffffff5280, inst=0x55558b6af5e0)
    at ~/src/swift/swift/lib/IRGen/LoadableByAddress.cpp:4640
#11 runPeepholesAndReg2Mem (pm=pm@entry=0x7fffffff6348, 
    silMod=silMod@entry=0x55556b260610, irgenModule=0x55559695a830)
    at ~/src/swift/swift/lib/IRGen/LoadableByAddress.cpp:4777
...
(gdb) select 11
(gdb) call i->dump()
  %185 = unchecked_bitwise_cast %1 : $EmptyCollection<Character> to $Slice<AttributedString.CharacterView> // users: %216, %241, %219, %186, %187, %188, %190

Forcibly dumping the silMod (silMod->dump("...some file", true); at the start of runPeepholesAndReg2Mem) and examining the output shows this is related to

// specialized AttributedString.CharacterView.replaceSubrange<A>(_:with:)
sil shared @$s20FoundationEssentials16AttributedStringV13CharacterViewV15replaceSubrange_4withySnyAC5IndexVG_xtSlRzSJ7ElementRtzlFAE_Tg5 : $@convention(method) (@in_guaranteed Range<AttributedString.Index>, @in_guaranteed AttributedString.CharacterView, @inout AttributedString.CharacterView) -> () {
// %0 "subrange"                                  // users: %49, %16, %18, %34
// %1 "newElements"                               // users: %130, %138, %133, %122, %121, %15, %14, %13, %124
// %2 "self"                                      // users: %137, %20, %47, %17
bb0(%0 : $*Range<AttributedString.Index>, %1 : $*AttributedString.CharacterView, %2 : $*AttributedString.CharacterView):
...
bb4:                                              // Preds: bb2
  %185 = unchecked_bitwise_cast %1 to $Slice<AttributedString.CharacterView> // users: %216, %241, %219, %186, %187, %188, %190; line:120:12:minlined: specialized AttributedString.CharacterView.replaceSubrange<A>(_:with:) perf_inlined_at line:301:37

Note this is an unchecked_bitwise_cast instruction but looks slightly different from the SILInstruction::dump, but this looks like it is the closest thing that seems to be related.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.crashBug: A crash, i.e., an abnormal termination of softwaretriage neededThis issue needs more specific labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions