Skip to content

Rebranch: Silent assembler failure on arm64 Windows #11377

@Steelskin

Description

@Steelskin

tl;dr version

There are 3 issues at play here:

  1. LLVM is failing to generate SEH end prologue properly for arm64 in some cases.
  2. The error message is never surfaced and the compilation silently succeeds, with an empty object file being generated.
  3. It seems likely that the SIL LICM pass is doing something to generate LLVM IR that the LLVM arm64 frame lowering code does not handle properly.

I have a potential fix for issue 1 but I still need to figure out a reproducer for it and land it in upstream LLVM main.

Long version

Symptom

The Swift toolchain rebranch is currently failing on Windows arm64 because a target in swift-build is failing to link. Further analysis has revealed that this is due to an empty object file. Here is the diagnostic output from the linker:

FAILED: bin/SWBTaskExecution.dll lib/SWBTaskExecution.lib
C:\WINDOWS\system32\cmd.exe /C "cd . && S:\b\5\bin\swiftc.exe -target aarch64-unknown-windows-msvc -j 10 -num-threads 10 -emit-library -use-ld=lld-link -sdk "S:/Program Files/Swift/Platforms/Windows.platform/Developer/SDKs/Windows.sdk" -g -debug-info-format=dwarf -use-ld=lld-link -Xlinker /DEBUG:DWARF -Xlinker /INCREMENTAL:NO -Xlinker /OPT:REF -Xlinker /OPT:ICF -O -swift-version 5 -libc MD   -Xlinker -implib:lib\SWBTaskExecution.lib   -o bin\SWBTaskExecution.dll @CMakeFiles\SWBTaskExecution.rsp && cd ."
<unknown>:0: warning: using (deprecated) legacy driver, Swift installation does not contain swift-driver at: 'C:\Users\fabrice\src\toolchain\b\5\bin\swift-driver-new.exe'
lld-link: error: Sources\SWBTaskExecution\CMakeFiles\SWBTaskExecution.dir\BuildDescriptionManager.swift.obj: unknown file type
clang: error: linker command failed with exit code 1 (use -v to see invocation)
[...]
$ file ./Sources/SWBTaskExecution/CMakeFiles/SWBTaskExecution.dir/BuildDescriptionManager.swift.obj
./Sources/SWBTaskExecution/CMakeFiles/SWBTaskExecution.dir/BuildDescriptionManager.swift.obj: empty

Investigation

Dumping diagnostic information in LLVM has revealed that the issue comes from this block in LLVM:

uint64_t WinCOFFObjectWriter::writeObject() {
  // If the assember had an error, then layout will not have completed, so we
  // cannot write an object file.
  if (getContext().hadError())
    return 0;
  // [...]
}

After adding more diagnostic in MCContext::reportError(), it turns out that the following error message was silently dropped, this is issue 2:

error: starting epilogue (.seh_startepilogue) before prologue has ended (.seh_endprologue) in $s16SWBTaskExecution23BuildDescriptionManagerC09constructcD0_11planRequest9signature11inDirectory2fs17bypassActualTasks19planningDiagnostics8delegateAA0cD0CSg0A12Construction0C4PlanC_AO0ctH0V7SWBUtil10ByteStringVAT4PathVAT7FSProxy_pSbSDy7SWBCore16ConfiguredTargetCSgSayAT10DiagnosticVGGAA0cdS8Delegate_ptYaKFZTf4nnnnnnnnd_n
error: Stray .seh_endepilogue in $s16SWBTaskExecution23BuildDescriptionManagerC09constructcD0_11planRequest9signature11inDirectory2fs17bypassActualTasks19planningDiagnostics8delegateAA0cD0CSg0A12Construction0C4PlanC_AO0ctH0V7SWBUtil10ByteStringVAT4PathVAT7FSProxy_pSbSDy7SWBCore16ConfiguredTargetCSgSayAT10DiagnosticVGGAA0cdS8Delegate_ptYaKFZTf4nnnnnnnnd_n

For reference, here are the corresponding ASM and LLVM IR dumps for this file:
BuildDescriptionManager.swift.asm.txt
BuildDescriptionManager.swift.llvm-ir.txt

It turns out that the problematic function does not have a .seh_endprologue section, resulting in the assembler failure, this is issue 1.

The issue seems to be triggered by a Swift optimization pass, since adding @_optimize(none) on the problematic function fixes the issue. Given recent changes, it seems likely that the SIL LICM pass is doing something that the frame lowering code does not like, this is issue 3.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions