Skip to content

[llvm] Drop four LLVM tuning knobs that never reached codegen - #1153

Merged
coderfeli merged 1 commit into
mainfrom
phil/drop-inert-llvm-knobs
Sep 20, 2026
Merged

coderfeli merged 1 commit into
mainfrom
phil/drop-inert-llvm-knobs

Conversation

@Phil-amd

Copy link
Copy Markdown
Member

What

Four LLVM tuning knobs in this tree never reached codegen. Removes them.

Why they did nothing

gpu-module-to-binary{opts=...} is never read on AMD: tokenizeCmdOptions()
has only XeVM and NVVM callers, and assembleIsa() takes no flags parameter.
The two flags routed through it were never flags anyway -- amdgpu-waves-per-eu
and amdgpu-num-vgpr are IR function attributes, which llc rejects.
waves_per_eu survives only because lower_compile_hints also sets the rocdl
attribute.

Knob Why inert
maxnreg No attribute path -- while autotune.Config searched over it
amdgpu-schedule-regions Not a cl::opt in the pin; llc rejects it
amdgpu-expert-scheduling-mode on gfx942 Gated getGeneration() >= GFX12
FLYDSL_LLVM_ENABLE_POST_MISChed Casing typo; the documented spelling never applied

None was harmless: an unknown hint still changes the JIT cache key, so each
produced a real recompile that behaved exactly like setting nothing.

⚠ Behaviour change: the maxnreg hint now raises ValueError and
Config(maxnreg=...) raises TypeError -- **kwargs would otherwise swallow
it as a Constexpr arg. Use waves_per_eu. Autotune caches written earlier still
load; the stale key is dropped, not rejected.

Testing

Every claim verified against the pinned LLVM (e2a39f504), each with a positive
control established before any negative was recorded. gfx942
expert-scheduling-mode is the example: toggling it leaves gfx942/gfx950
byte-identical while changing gfx1250 visibly, so the instrument reads and the
gfx942 result is a real negative. Config unit tests pass; ruff and black clean.

Comment thread kernels/attention/flash_attn_generic.py Outdated
Comment thread python/flydsl/compiler/backends/rocm.py Outdated
@Phil-amd
Phil-amd force-pushed the phil/drop-inert-llvm-knobs branch 2 times, most recently from 4f572fd to a14afdf Compare September 18, 2026 06:16
@jli-melchior

Copy link
Copy Markdown
Collaborator

minor documentation follow-up: base.py and kernel_function.py still describe maxnreg as a supported compiler hint, but this PR now rejects it. Could we update those references to match the new behavior?

@Phil-amd
Phil-amd force-pushed the phil/drop-inert-llvm-knobs branch from a14afdf to be7c643 Compare September 18, 2026 08:00
@Phil-amd

Phil-amd commented Sep 18, 2026 •

Copy link
Copy Markdown
Member Author

Done — fixed in be7c643:

  • base.py: dropped maxnreg from the pipeline_fragments docstring
  • kernel_function.py: the thread-local comment now says waves_per_eu, fast_fp_math

`gpu-module-to-binary{opts=...}` is never read on AMD: tokenizeCmdOptions()
has only XeVM and NVVM callers, and assembleIsa() takes no flags parameter.
The two flags routed through it were never flags anyway -- amdgpu-waves-per-eu
and amdgpu-num-vgpr are IR function attributes, which llc rejects. waves_per_eu
survives only because lower_compile_hints also sets the rocdl attribute.

maxnreg had no such path and stayed inert while autotune searched over it, so
it now raises; Config(maxnreg=...) raises too, since **kwargs would otherwise
swallow it as a Constexpr arg. Caches written earlier still load -- the stale
key is dropped, not rejected. Also drop amdgpu-schedule-regions (not a cl::opt
in the pin), expert-scheduling-mode on gfx942 (gated GFX12+, and toggling it
leaves gfx942/gfx950 byte-identical while changing gfx1250 visibly), and fix
the FLYDSL_LLVM_ENABLE_POST_MISChed casing typo. bin_cli_opts is left empty
with a comment, so nothing is routed through the dead lane again.

None was harmless: an unknown hint still changes the JIT cache key, so each
produced a real recompile that behaved exactly like setting nothing.
@Phil-amd
Phil-amd force-pushed the phil/drop-inert-llvm-knobs branch from be7c643 to acf5331 Compare September 18, 2026 08:08
@Phil-amd

Copy link
Copy Markdown
Member Author

Folded the documentation mentions into this PR as well (acf5331), so maxnreg is consistent everywhere in one go:

  • docs/kernel_tuning_guide.md, prefetch-data-load, kernel-trace-analysis — the three "do not use maxnreg" warnings now state it has been removed, keeping the measured 4.5x figure since that is why it went
  • flydsl-kernel-authoring — one more I found while sweeping: it still listed Config.maxnreg as a supported compiler-level option

Now 11 files. Style gate and check_repo.py pass.

@coderfeli
coderfeli merged commit 6c5e39d into main Sep 20, 2026
16 checks passed
@coderfeli
coderfeli deleted the phil/drop-inert-llvm-knobs branch September 20, 2026 01:07
Phil-amd added a commit that referenced this pull request Sep 20, 2026
Nothing in the tree could answer "which LLVM knob do I turn, and did it
apply?" -- a grep of all 17 SKILL.md files finds no -mllvm, llc, opt or
mlir-opt recipe anywhere. That gap is what let the four inert knobs removed
in #1153 sit there unnoticed: a knob that silently does nothing looks
exactly like one that works: an unknown hint still forces a recompile.

So the skill leads with verification, not with the knob list. Every recipe
pairs an artifact grep with a mandatory negative control: misspell the key,
and the assertion must fail; if it still passes, the instrument is dead.
Ships per-arch references for gfx950 and gfx1250, whose occupancy knobs are
not interchangeable, and two scripts proven against both controls.

Cross-references added to the four sibling skills that lead here; nothing
discovers a skill automatically. flydsl-kernel-authoring also had two
mis-attributions about the dead opts= lane, corrected in passing.
Phil-amd added a commit that referenced this pull request Sep 20, 2026
Nothing in the tree could answer "which LLVM knob do I turn, and did it
apply?" -- a grep of all 17 SKILL.md files finds no -mllvm, llc, opt or
mlir-opt recipe anywhere. That gap is what let the four inert knobs removed
in #1153 sit there unnoticed: a knob that silently does nothing looks
exactly like one that works, since an unknown hint still forces a
recompile.

So the skill leads with verification, not with the knob list. Every recipe
pairs an artifact grep with a mandatory negative control: misspell the key,
and the assertion must fail; if it still passes, the instrument is dead.
Ships per-arch references for gfx950 and gfx1250, whose occupancy knobs are
not interchangeable, and two scripts proven against both controls.

Cross-references added to the four sibling skills that lead here; nothing
discovers a skill automatically. flydsl-kernel-authoring also had two
mis-attributions about the dead opts= lane, corrected in passing.
Phil-amd added a commit that referenced this pull request Sep 20, 2026
Nothing in the tree could answer "which LLVM knob do I turn, and did it
apply?" -- a grep of all 17 SKILL.md files finds no -mllvm, llc, opt or
mlir-opt recipe anywhere. That gap is what let the four inert knobs removed
in #1153 sit there unnoticed: a knob that silently does nothing looks
exactly like one that works, since an unknown hint still forces a
recompile.

So the skill leads with verification, not with the knob list. Every recipe
pairs an artifact grep with a mandatory negative control: misspell the key,
and the assertion must fail; if it still passes, the instrument is dead.
Ships per-arch references for gfx950 and gfx1250, whose occupancy knobs are
not interchangeable, and two scripts proven against both controls.

Cross-references added to the four sibling skills that lead here; nothing
discovers a skill automatically. flydsl-kernel-authoring also had two
mis-attributions about the dead opts= lane, corrected in passing.
Phil-amd added a commit that referenced this pull request Sep 20, 2026
Nothing in the tree could answer "which LLVM knob do I turn, and did it
apply?" -- a grep of all 17 SKILL.md files finds no -mllvm, llc, opt or
mlir-opt recipe anywhere. That gap is what let the four inert knobs removed
in #1153 sit there unnoticed: a knob that silently does nothing looks
exactly like one that works, since an unknown hint still forces a
recompile.

So the skill leads with verification, not with the knob list. Every recipe
pairs an artifact grep with a mandatory negative control: misspell the key,
and the assertion must fail; if it still passes, the instrument is dead.
Ships per-arch references for gfx950 and gfx1250, whose occupancy knobs are
not interchangeable, and two scripts proven against both controls.

Cross-references added to the four sibling skills that lead here; nothing
discovers a skill automatically. flydsl-kernel-authoring also had two
mis-attributions about the dead opts= lane, corrected in passing.
Phil-amd added a commit that referenced this pull request Sep 20, 2026
Nothing in the tree could answer "which LLVM knob do I turn, and did it
apply?" -- a grep of all 17 SKILL.md files finds no -mllvm, llc, opt or
mlir-opt recipe anywhere. That gap is what let the four inert knobs removed
in #1153 sit there unnoticed: a knob that silently does nothing looks
exactly like one that works, since an unknown hint still forces a
recompile.

So the skill leads with verification, not with the knob list. Every recipe
pairs an artifact grep with a mandatory negative control: misspell the key,
and the assertion must fail; if it still passes, the instrument is dead.
Ships per-arch references for gfx950 and gfx1250, whose occupancy knobs are
not interchangeable, and two scripts proven against both controls.

Cross-references added to the four sibling skills that lead here; nothing
discovers a skill automatically. flydsl-kernel-authoring also had two
mis-attributions about the dead opts= lane, corrected in passing.
Phil-amd added a commit that referenced this pull request Sep 21, 2026
Nothing in the tree could answer "which LLVM knob do I turn, and did it
apply?" -- a grep of all 17 SKILL.md files finds no -mllvm, llc, opt or
mlir-opt recipe anywhere. That gap is what let the four inert knobs removed
in #1153 sit there unnoticed: a knob that silently does nothing looks
exactly like one that works, since an unknown hint still forces a
recompile.

So the skill leads with verification, not with the knob list. Every recipe
pairs an artifact grep with a mandatory negative control: misspell the key,
and the assertion must fail; if it still passes, the instrument is dead.
Ships per-arch references for gfx950 and gfx1250, whose occupancy knobs are
not interchangeable, and two scripts proven against both controls.

Cross-references added to the four sibling skills that lead here; nothing
discovers a skill automatically. flydsl-kernel-authoring also had two
mis-attributions about the dead opts= lane, corrected in passing.
coderfeli pushed a commit that referenced this pull request Sep 22, 2026
Nothing in the tree could answer "which LLVM knob do I turn, and did it
apply?" -- a grep of all 17 SKILL.md files finds no -mllvm, llc, opt or
mlir-opt recipe anywhere. That gap is what let the four inert knobs removed
in #1153 sit there unnoticed: a knob that silently does nothing looks
exactly like one that works, since an unknown hint still forces a
recompile.

So the skill leads with verification, not with the knob list. Every recipe
pairs an artifact grep with a mandatory negative control: misspell the key,
and the assertion must fail; if it still passes, the instrument is dead.
Ships per-arch references for gfx950 and gfx1250, whose occupancy knobs are
not interchangeable, and two scripts proven against both controls.

Cross-references added to the four sibling skills that lead here; nothing
discovers a skill automatically. flydsl-kernel-authoring also had two
mis-attributions about the dead opts= lane, corrected in passing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants