Skip to content

fix(x86): stop leaking AVX-512/AMX flags into the Target IR dialect - #564

Merged
gstoner merged 1 commit into
mainfrom
fix/x86-dialect-avx512-flag-leak
Aug 15, 2026
Merged

gstoner merged 1 commit into
mainfrom
fix/x86-dialect-avx512-flag-leak

Conversation

@gstoner

@gstoner gstoner commented Aug 15, 2026

Copy link
Copy Markdown
Owner

Fixes the Validate / lit failure in run 31893492411 — 14 x86 fixtures crashing inside TesseraX86Dialect::initialize().

Root cause: a build-flag leak, not an IR defect

The dialect and its TileType registration were always correct.

add_compile_options(-mavx512f …) is directory scoped, and add_subdirectory(lib/IR) sat below that call — so the hardware-free Target IR dialect was compiled with all 11 AVX-512/AMX flags. The compiler was then entitled to emit an AVX-512-only encoding into dialect registration itself. Confirmed by disassembling the TU: vpbroadcastq %rgpr, %xmm, a GPR-source broadcast that exists only under AVX-512.

The tell was the signal, not the backtrace. All 14 fixtures failed with SIGILL (signal 4) at one identical address, not SIGSEGV. An illegal instruction is a build-configuration fact; Dialect::addType<TileType>() was merely the first code from that object file to execute.

This is also why the P0 was closed in good faith on Zen 5 and reopened by CI: Zen 5 has AVX-512, so the instruction is legal there. The GitHub runner does not.

Fix

  • Flags collected into TESSERA_X86_ARCH_FLAGS, applied with target_compile_options to this directory's kernel targets, enumerated via BUILDSYSTEM_TARGETS. A future kernel target is covered automatically; subdirectories are structurally excluded. No ordering left for a reader to maintain by hand — the previous arrangement was correct only until someone added a subdirectory below it.
  • tessera_x86_base stays excluded so its baseline pin isn't silently re-enabled.
  • lib/IR/CMakeLists.txt fails configure if any host-specific ISA flag is in scope (Decision #21a, fail closed), so the next occurrence is a build error naming the cause rather than a runtime SIGILL that reads as a corrupt MLIR install.

Verification

Check Result
Dialect TU compile flags, before 11 arch flags (-mavx512f … -mamx-bf16)
Dialect TU compile flags, after none
Kernel TU (avx512_gemm_bf16.cpp) unchanged, all 11
tessera_x86_base unchanged, baseline pin intact
ninja tessera-opt clean; tessera_x86 registers
x86_dialect_load / x86_target_ir / x86_target_ir_invalid pass
Guard negative test (leak reintroduced) configure fails with the naming message

Acceptance evidence is the green lit lane on the non-AVX-512 runner, not a local rebuild — hence the lit-smoke label.

Separate defect documented, not fixed

TileToX86Pass.cpp:1045 calls getOrLoadDialect("tessera_x86") from inside runOnOperation(). MLIR forbids loading a dialect during pass execution: it's a hard LLVM ERROR on assertions-enabled LLVM (fails 12 of the 15 x86 fixtures) and silent UB on the NDEBUG build CI uses — CI structurally cannot catch it.

Left unfixed deliberately: the canonical remedy is getDependentDialects(), which needs the C++ type and therefore couples TesseraPasses to the optional TesseraX86IR. TesseraPasses links no backend Target IR library today, so that's a new dependency direction under Decisions #19/#31 — an owner call, not a bug edit. The todo records the recommended TESSERA_HAS_X86_TARGET_IR-guarded shape, and notes that Pass::initialize() is not an escape hatch (its contract explicitly forbids loading dialects).

Docs

🤖 Generated with Claude Code

`X86-DIALECT-LOAD-CRASH-2026-08-12` was a build-flag leak, not an IR defect.

The x86 kernel project applied its detected AVX-512/AMX flags with
`add_compile_options`, which is *directory* scoped, and `add_subdirectory(lib/IR)`
sat below that call. The hardware-free Target IR dialect was therefore compiled
`-mavx512f -mavx512bw ... -mamx-tile ...`, and the compiler was entitled to emit
an AVX-512-only encoding into dialect registration itself (confirmed by
disassembly: `vpbroadcastq %rgpr, %xmm`, a GPR-source broadcast that exists only
under AVX-512).

On a host with AVX-512 that runs fine, which is why this P0 was closed in good
faith on Zen 5. On the CI runner it is not, and `tessera-opt` died the first time
it touched the dialect. The tell was the signal, not the backtrace: all 14
fixtures failed with SIGILL (signal 4) at one identical address, not SIGSEGV.
`Dialect::addType<TileType>()` was merely the first code from that translation
unit to execute.

Flags are now collected into `TESSERA_X86_ARCH_FLAGS` and applied with
`target_compile_options` to this directory's kernel targets, enumerated via
`BUILDSYSTEM_TARGETS` so a later kernel target is covered automatically while
subdirectories are structurally excluded. `tessera_x86_base` stays excluded so
its baseline pin is not silently re-enabled.

`lib/IR/CMakeLists.txt` additionally fails configure if any host-specific ISA
flag is in scope, so the next occurrence is a build error naming the cause
rather than a runtime SIGILL that reads as a corrupt MLIR install (Decision
21a, fail closed). Negative-tested by reintroducing the leak.

Verified: dialect TU goes from 11 arch flags to none while kernel TUs are
unchanged; `tessera-opt` builds and registers `tessera_x86`;
`x86_dialect_load.mlir`, `x86_target_ir.mlir` and the verifier-negative
`x86_target_ir_invalid.mlir` pass.

Docs record the root cause and the standing lesson: a host that has the ISA
cannot falsify a host-portability claim, so Decision #19's "lit-testable on any
host" is only evidenced by a host without AVX-512.

Also documents a distinct, still-open defect found while verifying this one:
`TileToX86Pass` loads `tessera_x86` from inside `runOnOperation()`, which MLIR
forbids. It is a hard error on assertions-enabled LLVM and silent UB on the
NDEBUG build CI uses. Left unfixed because the canonical remedy couples
`TesseraPasses` to the optional `TesseraX86IR` — a layering call under
Decisions #19/#31, not a bug edit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@gstoner
gstoner merged commit 98282bd into main Aug 15, 2026
25 of 28 checks passed
@gstoner
gstoner deleted the fix/x86-dialect-avx512-flag-leak branch August 15, 2026 18:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant