You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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"CACHESTRING"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.0 → 2026.5.2, v0.42.0 → 2026.5.2, v0.43.0 → 2026.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:
The 2026.12.x patch line does not carry the fix. A patch-level move off 2026.12 is not sufficient.
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.1 → ahead_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...33f9ed0c → identical.
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):
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
Perf. The last pin move was a downgrade — Downgrade 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.
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.
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:85onmain:Mechanism: the version is interpolated into both the release tag and the asset filename (
external/CMakeLists.txt:87) and fetched bysgl_download_package(external/CMakeLists.txt:10-22) — a prebuilt release tarball, not a submodule or SHA, with noURL_HASH.Per released tag:
v0.41.0→2026.5.2,v0.42.0→2026.5.2,v0.43.0→2026.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, viagh 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:
statusaheadaheadaheadaheadbehindbehinddivergedbehindbehindTwo traps here, both of which would produce a bump that appears to fix this and doesn't:
2026.12.xpatch line does not carry the fix. A patch-level move off 2026.12 is not sufficient.v2026.12.0.1is 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.1→ahead_by=1, behind_by=0, i.e.v2026.12plus one commit (f17d619e, "Memoize shared Val and type DAG traversals (#12106)"). Against the fix it isdivergedwithahead_by=134, behind_by=1— the tag is missing 134 commits that the fix side has. Its assets follow the sameslang-2026.12.0.1-<platform>naming thatexternal/CMakeLists.txt:87builds, so it is a selectable value forSGL_SLANG_VERSIONthat 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 fromahead; both mean the fix is absent, and onlybehind/identicalmean it is present. Verified with a positive control:compare/33f9ed0c...33f9ed0c→identical.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.
This agrees with the table above:
v2026.13andv2026.14.1return33f9ed0ceae1;v2026.12andv2026.12.0.1returna7fbf1ab0e9d.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_64release assets and compiling a minimal Neumaier-style compensated-summation kernel with each:slangc -vNoContractionunder-fp-mode preciseslang-2026.12.0.1-linux-x86_64.tar.gz2026.12.0.1slang-2026.14.1-linux-x86_64.tar.gz2026.14.1Controls: with the default fp-mode both emit 0, so the decorations are attributable to
-fp-mode preciserather than to the version; and theOpFAdd+OpExtInstcount is 6 in both, i.e. the same instruction graph is being decorated rather than a different one being generated. This makes the2026.12.0.1hazard empirical, not inferred.SlangPy does reach the fixed code path:
src/sgl/device/shader.cpp:455-456setstarget_desc.floatingPointModeandCompilerOptionName::FloatingPointModeper target — i.e. the global-fp-mode precisethat #11935 fixed, as opposed to the per-variableprecisequalifier still tracked by shader-slang/slang#12198.Proposed change
Bump
external/CMakeLists.txt:85to 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) — presentslang-standard-module-${VER}(external/CMakeLists.txt:168,205-209) — presentlib/libslang-compiler.so.0.2026.14.1.dwarfand Windowsslang-compiler.pdb(external/CMakeLists.txt:192,201-202,213,SGL_SLANG_DEBUG_INFOdefaults ON) — presentNo other file pins the version (
git grep SGL_SLANG_VERSION→ only this file plus adocs/changelog.rstmention);SLANG_BUILD_TAGis queried at runtime viaspGetBuildTagString(); there are no#if SLANG_VERSIONguards insrc/orslangpy/.Open questions for a maintainer
.github/workflows/ci-benchmark.ymlthe "Build latest Slang" step (line 75) and theSGL_LOCAL_SLANGconfigure 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.SLANG_RHI_FETCH_SLANGisOFF(external/CMakeLists.txt:231,237-239) and slangpy hands its own Slang dirs to slang-rhi, so rhi builds against the bundled Slang. Should theexternal/slang-rhisubmodule (currently1a97687, 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.ymlbuildsmainagainst Slang master withSGL_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 Slangmaster, 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.