Skip to content

Bundled Slang pin (2026.12) predates the -fp-mode precise NoContraction fix — blocks shader-slang/slang#12285 for SlangPy users #1092

Description

@nv-slang-bot

Summary

SlangPy bundles a pinned prebuilt Slang release, and that pin currently predates the upstream fix for global -fp-mode precise. As a result a SlangPy user cannot get the fix no matter which Slang version is released, and must keep an [noinline] workaround.

This is the SlangPy-side residual of shader-slang/slang#12285 (Vulkan: precise FMA-based compensated summation is wrong unless the correction helper is [noinline]). The compiler-side work is already done and released — this issue tracks only the dependency bump.

The pin

external/CMakeLists.txt:85 on main:

set(SGL_SLANG_VERSION "2026.12" CACHE STRING "Slang version to download when not using a local build")

Mechanism: the version is interpolated into both the release tag and the asset filename (external/CMakeLists.txt:87) and fetched by sgl_download_package (external/CMakeLists.txt:10-22) — a prebuilt release tarball, not a submodule or SHA, with no URL_HASH.

Per released tag: v0.41.02026.5.2, v0.42.02026.5.2, v0.43.02026.12, v0.43.1 (latest) → 2026.12. The reporter in slang#12285 was on SlangPy 0.41.0, i.e. 2026.5.2.

Why 2026.12 is not enough

The fix is slang PR shader-slang/slang#11935, commit 33f9ed0c ("Emit NoContraction under -fp-mode precise on direct SPIR-V", 2026-07-07). Containment per release tag, via gh api repos/shader-slang/slang/compare/<tag>...33f9ed0c --jq .status (ahead = fix absent, behind = fix present):

Ordered by publish date, which is the point of the table:

Slang tag Published status Fix present?
v2026.5.2 2026-03-31 ahead
v2026.12 2026-06-25 ahead
v2026.12.1 2026-06-30 ahead
v2026.12.2 2026-07-01 ahead
v2026.13 2026-07-08 behind
v2026.13.1 2026-07-13 behind
v2026.12.0.1 2026-07-16 diverged
v2026.14 2026-07-24 behind
v2026.14.1 (latest release) 2026-07-30 behind

Two traps here, both of which would produce a bump that appears to fix this and doesn't:

  1. The 2026.12.x patch line does not carry the fix. A patch-level move off 2026.12 is not sufficient.
  2. v2026.12.0.1 is the nastiest case. It was published 2026-07-16 — later than v2026.13.1 — so by publish date it looks like the newest thing available, yet it is a patch cut from the older 2026.12 branch: compare/v2026.12...v2026.12.0.1ahead_by=1, behind_by=0, i.e. v2026.12 plus one commit (f17d619e, "Memoize shared Val and type DAG traversals (#12106)"). Against the fix it is diverged with ahead_by=134, behind_by=1 — the tag is missing 134 commits that the fix side has. Its assets follow the same slang-2026.12.0.1-<platform> naming that external/CMakeLists.txt:87 builds, so it is a selectable value for SGL_SLANG_VERSION that silently lacks the fix.

Note also that the GitHub REST compare status has four values — ahead, behind, identical, diverged. diverged (shares history, neither side contains the other) is a distinct case from ahead; both mean the fix is absent, and only behind/identical mean it is present. Verified with a positive control: compare/33f9ed0c...33f9ed0cidentical.

A less error-prone formulation of the same question, for anyone re-checking: the tag contains the fix iff the merge base equals the fix commit.

fix=$(gh api repos/shader-slang/slang/commits/33f9ed0c --jq .sha)
gh api "repos/shader-slang/slang/compare/$fix...<TAG>" --jq '.merge_base_commit.sha'
# equals $fix  -> tag contains the fix

This agrees with the table above: v2026.13 and v2026.14.1 return 33f9ed0ceae1; v2026.12 and v2026.12.0.1 return a7fbf1ab0e9d.

Confirmed against the shipped binaries, not just tag ancestry

Commit ancestry alone would not prove the published artifact behaves differently (a release could in principle carry a cherry-pick under another SHA). So this was checked directly, by downloading the official linux-x86_64 release assets and compiling a minimal Neumaier-style compensated-summation kernel with each:

release asset slangc -v NoContraction under -fp-mode precise
slang-2026.12.0.1-linux-x86_64.tar.gz 2026.12.0.1 0
slang-2026.14.1-linux-x86_64.tar.gz 2026.14.1 8

Controls: with the default fp-mode both emit 0, so the decorations are attributable to -fp-mode precise rather than to the version; and the OpFAdd+OpExtInst count is 6 in both, i.e. the same instruction graph is being decorated rather than a different one being generated. This makes the 2026.12.0.1 hazard empirical, not inferred.

SlangPy does reach the fixed code path: src/sgl/device/shader.cpp:455-456 sets target_desc.floatingPointMode and CompilerOptionName::FloatingPointMode per target — i.e. the global -fp-mode precise that #11935 fixed, as opposed to the per-variable precise qualifier still tracked by shader-slang/slang#12198.

Proposed change

Bump external/CMakeLists.txt:85 to the latest release, 2026.14.1 (published 2026-07-30).

Pre-flight checks already done — every version-shaped path in the build resolves in the real 2026.14.1 archives on all four platform archives (linux-x86_64, linux-aarch64, macos-aarch64, windows-aarch64):

  • libslang-glslang-${VER} / libslang-glsl-module-${VER} (external/CMakeLists.txt:162,198-199) — present
  • slang-standard-module-${VER} (external/CMakeLists.txt:168,205-209) — present
  • debug-info lib/libslang-compiler.so.0.2026.14.1.dwarf and Windows slang-compiler.pdb (external/CMakeLists.txt:192,201-202,213, SGL_SLANG_DEBUG_INFO defaults ON) — present

No other file pins the version (git grep SGL_SLANG_VERSION → only this file plus a docs/changelog.rst mention); SLANG_BUILD_TAG is queried at runtime via spGetBuildTagString(); there are no #if SLANG_VERSION guards in src/ or slangpy/.

Open questions for a maintainer

  1. Perf. The last pin move was a downgradeDowngrade slang to version 2026.5.2 #1016, "Newer slang releases have severe perf regressions" — reverting Update slang to version 2026.10.2 #1012 one day later. And in .github/workflows/ci-benchmark.yml the "Build latest Slang" step (line 75) and the SGL_LOCAL_SLANG configure line (line 104) are both commented out, so the benchmark lane measures the pinned Slang and structurally cannot detect a 2026.14.1 regression. There is currently no perf evidence for ≥2026.13. This seems like the decisive question.
  2. slang-rhi lockstep. SLANG_RHI_FETCH_SLANG is OFF (external/CMakeLists.txt:231,237-239) and slangpy hands its own Slang dirs to slang-rhi, so rhi builds against the bundled Slang. Should the external/slang-rhi submodule (currently 1a97687, 2026-07-06; upstream ~1 month ahead) move at the same time, as in Update to slang 2026.12 #1037? If it does, src/sgl/device/types.h:124 (static_assert(Feature::count == rhi::Feature::_Count)) is where it will break. A Slang-only bump does not trip that assert.

Supporting signal

.github/workflows/ci-latest-slang.yml builds main against Slang master with SGL_LOCAL_SLANG=ON, bypassing the pin. Recent nightly (event=schedule) history: 11 success / 3 failure of the last 14, with the latest run green on all 6 matrix cells ({windows, linux, macos} × {Debug, Release}) on 2026-08-05 — six nights after 2026.14.1 was published. The three failures (2026-07-23/24/25) failed inside the "Build Slang" step on a transient broken Slang master, with no slangpy files involved.

Two limits on that signal, stated plainly: it builds Slang from source at master, not the released 2026.14.1 tarball, so tarball/wheel packaging is not exercised by it; and it is correctness-only, so it says nothing about question 1.

Refs: shader-slang/slang#12285 · shader-slang/slang#11935 · #1037 · #1016 · #1012

🤖 Generated by an automated SlangPy coworker — may be inaccurate. A human maintainer should verify.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions