Skip to content

Restore auto-diff link gating to the final codegen link#11779

Merged
jvepsalainen-nv merged 8 commits into
shader-slang:masterfrom
jvepsalainen-nv:fix-9808-link-perf-regression
Jul 7, 2026
Merged

Restore auto-diff link gating to the final codegen link#11779
jvepsalainen-nv merged 8 commits into
shader-slang:masterfrom
jvepsalainen-nv:fix-9808-link-perf-regression

Conversation

@jvepsalainen-nv

@jvepsalainen-nv jvepsalainen-nv commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Fixes #11781

Motivation

Auto-diff refactor caused compile-time perf regression
between releases 2026.5 and 2026.7, visible in the compile-perf suite
(tools/compile-perf). The "per-compile floor" workloads regressed sharply:
e.g. the minimal (empty shader) linkIR rose ~10-13x and linkAndOptimizeIR
rose similarly, and every compile pays this regardless of whether it uses
auto-diff.

Root cause

#9808 removed the useAutodiff gating that the IR linker previously used to
avoid pulling auto-diff artifacts into programs that do not differentiate:

  • shouldDeepCloneWitnessTable used to return useAutodiff for the
    IDifferentiable family; Refactor auto-diff implementation. #9808 made it return true unconditionally and
    also added the new IForwardDifferentiable / IBackwardDifferentiable /
    IBwdCallable interfaces to the always-deep-clone set. As a result every
    program deep-clones the differentiable-interface witness tables and all
    their entries (Differential, dzero, dadd, fwd/bwd methods).

  • The new cloneAnnotations step clones module-scope IRAnnotations for
    every cloned inst. Every AnnotationKind is differentiability-related
    (DifferentialType/Zero/Add/PairType, Forward/BackwardDerivative, ...), so
    this links a differentiable builtin's derivative associations into programs
    that never use them.

This dead auto-diff IR is then carried through specialize / simplifyIR / DCE
before finally being eliminated, inflating link and optimization time.

Fix

Restore the useAutodiff gating, but apply it ONLY to the final per-target
code-generation link (linkIR). A new IRSharedSpecContext::isFinalCodegenLink
flag is set true only there. The flag is required because the same clone paths
run during prelinkIR and module precompilation, whose output module must stay
complete and self-consistent (it may be serialized -- e.g. the core module).
Gating those paths corrupts the serialized core module and breaks auto-diff
code generation; gating only the throw-away per-target link is safe because
unused symbols are dropped on demand / by later DCE.

  • shouldDeepCloneWitnessTable: the differentiable-interface decision is now
    made BEFORE the generic [HLSLExport]/[KeepAlive] rule. Refactor auto-diff implementation. #9808 marks these
    witness tables [HLSLExport] (for cross-module auto-diff), which previously
    forced a deep clone regardless of gating. For the final codegen link of a
    non-differentiating program we now defer the entries and clone only those
    actually referenced.

  • cloneAnnotations: skip cloning annotations for the final codegen link when
    auto-diff is not in use.

Both gates fall back to the original (always-clone) behavior during prelink /
precompilation and whenever the program uses auto-diff, so auto-diff semantics
are unchanged.

Validation

  • minimal linkAndOptimizeIR: 0.79ms vs the pre-Refactor auto-diff implementation. #9808 parent's 1.87ms
    (the regressed value was ~15ms); linkIR back to ~0.1ms.
  • Auto-diff correctness: the interpreter (slangi) auto-diff tests under
    tests/autodiff/ produce correct numeric derivatives, and auto-diff HLSL /
    SPIR-V code generation no longer crashes, with the core module regenerated
    by the patched compiler.

Scope

This addresses the per-compile-floor / linkIR regression class. A separate,
larger codegen-side regression remains in simplifyIR for shaders that use
differentiable numeric builtins (sin/sqrt/...): #9808 wove differentiability
into the numeric type hierarchy (interface IFloat : IArithmetic, IDifferentiable,
plus the new differentiable interfaces), so a concrete non-auto-diff shader
transitively links float's entire differentiable-trait conformance closure.
That is tracked separately.


The remaining simplifyIR codegen-side regression described under Scope is tracked in issue #11780. Related broad perf-regression tracking: #11474.


Measured compile-perf effect (local)

Measured with tools/compile-perf/bench.py on macOS arm64 (Release), comparing this
branch (61e49c673) against its merge-base with master (803dff915). Both binaries
were built in the same fresh worktree configuration to avoid build-config skew.
Synthetic workloads: 1 warmup + 5 samples; mdl_dxr: 2 warmups + 9 samples; medians.

minimal (the per-compile floor this PR targets) — the fixed link-side cost is
removed for non-differentiating compiles:

timer base PR delta
linkAndOptimizeIR 2.37 ms 0.59 ms -75%
linkIR 0.24 ms 0.08 ms -67%
specializeModule 0.81 ms 0.05 ms -94%
simplifyIR 0.34 ms 0.06 ms -82%
generateOutput 3.85 ms 2.05 ms -47%
compileInner 10.42 ms 9.99 ms -4% (rest is front-end)

Stdevs on these timers are ±0.01–0.07 ms, so the deltas are unambiguous: ~1.8 ms of
fixed IR-side work is removed from every non-differentiating compile on this machine.

Other workloads:

  • Non-autodiff feature workloads improve modestly on link-side timers as the fixed
    saving amortizes: module_link -5.1% compileInner, specialization -3.4%,
    dynamic_dispatch linkIR -16%; sema_generics unchanged (front-end-dominated).
  • The autodiff workload is unchanged (+1.1% compileInner, within its noise) —
    expected, since the gate must not prune when auto-diff is in use.
  • loop_unroll is +2.5% compileInner (simplifyIR 55.5 -> 67.5 ms, ~9 stdevs, so
    real): the price of making the specialize-fixpoint cleanup group unconditional so
    [ForceUnroll] executes even when no round performs specialization work. It only
    shows on unroll-heavy stress shapes.
  • mdl_dxr (real-shader corpus) is neutral: -2.0% compileInner at ±2% noise, with
    link-side timers directionally better but not statistically distinguishable. This is
    expected: the PR removes a fixed per-compile cost, which a ~1 s codegen-dominated
    compile amortizes to ~0.2%; the benefit concentrates on the many-small-compiles
    pattern that the floor dominates.

Note the master baseline already includes earlier partial recoveries of the #9808
regression (e.g. the simplifyIR/linkIR restorations), so the floor delta here is
smaller than the original 10–13x figure measured against v2026.5 — this PR reclaims
the portion that was still outstanding.

…ion from shader-slang#9808)

Motivation
----------
PR shader-slang#9808 (auto-diff overhaul) caused a broad compile-time perf regression
between releases 2026.5 and 2026.7, visible in the compile-perf suite
(tools/compile-perf). The "per-compile floor" workloads regressed sharply:
e.g. the `minimal` (empty shader) `linkIR` rose ~10-13x and `linkAndOptimizeIR`
rose similarly, and every compile pays this regardless of whether it uses
auto-diff.

Root cause
----------
shader-slang#9808 removed the `useAutodiff` gating that the IR linker previously used to
avoid pulling auto-diff artifacts into programs that do not differentiate:

  * `shouldDeepCloneWitnessTable` used to return `useAutodiff` for the
    `IDifferentiable` family; shader-slang#9808 made it return `true` unconditionally and
    also added the new `IForwardDifferentiable` / `IBackwardDifferentiable` /
    `IBwdCallable` interfaces to the always-deep-clone set. As a result every
    program deep-clones the differentiable-interface witness tables and all
    their entries (`Differential`, `dzero`, `dadd`, fwd/bwd methods).

  * The new `cloneAnnotations` step clones module-scope `IRAnnotation`s for
    every cloned inst. Every `AnnotationKind` is differentiability-related
    (DifferentialType/Zero/Add/PairType, Forward/BackwardDerivative, ...), so
    this links a differentiable builtin's derivative associations into programs
    that never use them.

This dead auto-diff IR is then carried through specialize / simplifyIR / DCE
before finally being eliminated, inflating link and optimization time.

Fix
---
Restore the `useAutodiff` gating, but apply it ONLY to the final per-target
code-generation link (`linkIR`). A new `IRSharedSpecContext::isFinalCodegenLink`
flag is set true only there. The flag is required because the same clone paths
run during `prelinkIR` and module precompilation, whose output module must stay
complete and self-consistent (it may be serialized -- e.g. the core module).
Gating those paths corrupts the serialized core module and breaks auto-diff
code generation; gating only the throw-away per-target link is safe because
unused symbols are dropped on demand / by later DCE.

  * `shouldDeepCloneWitnessTable`: the differentiable-interface decision is now
    made BEFORE the generic `[HLSLExport]`/`[KeepAlive]` rule. shader-slang#9808 marks these
    witness tables `[HLSLExport]` (for cross-module auto-diff), which previously
    forced a deep clone regardless of gating. For the final codegen link of a
    non-differentiating program we now defer the entries and clone only those
    actually referenced.

  * `cloneAnnotations`: skip cloning annotations for the final codegen link when
    auto-diff is not in use.

Both gates fall back to the original (always-clone) behavior during prelink /
precompilation and whenever the program uses auto-diff, so auto-diff semantics
are unchanged.

Validation
----------
  * minimal `linkAndOptimizeIR`: 0.79ms vs the pre-shader-slang#9808 parent's 1.87ms
    (the regressed value was ~15ms); `linkIR` back to ~0.1ms.
  * Auto-diff correctness: the interpreter (slangi) auto-diff tests under
    tests/autodiff/ produce correct numeric derivatives, and auto-diff HLSL /
    SPIR-V code generation no longer crashes, with the core module regenerated
    by the patched compiler.

Scope
-----
This addresses the per-compile-floor / `linkIR` regression class. A separate,
larger codegen-side regression remains in `simplifyIR` for shaders that use
differentiable numeric builtins (`sin`/`sqrt`/...): shader-slang#9808 wove differentiability
into the numeric type hierarchy (`interface IFloat : IArithmetic, IDifferentiable`,
plus the new differentiable interfaces), so a concrete non-auto-diff shader
transitively links `float`'s entire differentiable-trait conformance closure.
That is tracked separately.
@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The linker now marks the final code-generation link in shared context and uses that flag to skip module-scope auto-diff annotation cloning and adjust witness-table deep cloning when autodiff is disabled.

Changes

Final codegen linking

Layer / File(s) Summary
Flag plumbing
source/slang/slang-ir-link.cpp
IRSharedSpecContext stores isFinalCodegenLink, and linkIR sets it on the final code-generation link path.
Annotation cloning gate
source/slang/slang-ir-link.cpp
cloneAnnotations skips module-scope IRAnnotation cloning when final codegen linking runs without autodiff.
Witness-table cloning gate
source/slang/slang-ir-link.cpp
shouldDeepCloneWitnessTable changes differentiability-related deep-clone decisions to depend on the final-link and autodiff state, while kIROp_ComInterfaceDecoration still triggers deep cloning.

Suggested reviewers

  • bmillsNV
  • jkwak-work
  • kaizhangNV
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: restoring auto-diff gating in the final codegen link.
Description check ✅ Passed The description matches the changeset and explains the performance regression fix and its scope.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: d20ea141-a9d7-426b-87fd-702d97c73572

📥 Commits

Reviewing files that changed from the base of the PR and between b1bdd88 and 1d6c26a.

📒 Files selected for processing (1)
  • source/slang/slang-ir-link.cpp

Comment thread source/slang/slang-ir-link.cpp Outdated
@jvepsalainen-nv jvepsalainen-nv self-assigned this Jun 26, 2026
@jvepsalainen-nv jvepsalainen-nv changed the title Restore auto-diff link gating to the final codegen link (perf regression from #9808) Restore auto-diff link gating to the final codegen link Jun 26, 2026
@jvepsalainen-nv jvepsalainen-nv marked this pull request as draft June 26, 2026 11:50
github-actions[bot]

This comment was marked as outdated.

@jvepsalainen-nv jvepsalainen-nv marked this pull request as ready for review July 2, 2026 18:52
github-actions[bot]

This comment was marked as outdated.

- shouldDeepCloneWitnessTable: restore the pre-shader-slang#9808 rule order so table-level
  [HLSLExport]/[KeepAlive] (user export, dynamic-dispatch type conformance) is
  honored before the differentiable-interface gate and can never lose entries
  to auto-diff pruning. The builtin differentiable-conformance tables carry
  neither decoration, so the gate still fires for them: -dump-ir output across
  all passes is byte-identical for non-differentiating shaders (minimal and
  sin-using probes), i.e. the perf win is unchanged. Also collapses the two
  walks over the conformance type's decorations into one.
- Introduce IRSharedSpecContext::canPruneAutodiffLinkArtifacts() as the single
  named definition of the pruning predicate (previously spelled twice with
  opposite polarity) and the canonical home of the safety argument; the field,
  cloneAnnotations, and shouldDeepCloneWitnessTable comments now state only
  site-specific facts and cross-reference it.
- Introduce isDifferentiableInterfaceBuiltin() next to KnownBuiltinDeclName as
  the authoritative definition of the differentiable-interface family.
- Document the invariants the gates rest on: a note at AnnotationKind that the
  linker assumes every kind is differentiability-related, and a contract
  comment on doesModuleUseAutodiff (no-false-negatives requirement, why
  module-scope scanning suffices for concrete translation requests, and the
  generic-dependent caveat).
- Comment accuracy fixes: the flag is about linkIR vs prelinkIR (module
  precompilation flows into linkIR and prunes safely); witness entries are
  cloned on demand, not dropped on demand; 'compile-time regression' instead
  of the ambiguous 'codegen regression'; acknowledge that IRBuiltinRequirementKey
  entries are still cloned eagerly rather than deferred.

Validated: slangc/slang-test/slangi rebuild cleanly; interpreter auto-diff
tests pass; SPIR-V validation passes on fwd_diff probes including a
generic-nested fwd_diff case.
github-actions[bot]

This comment was marked as outdated.

@jvepsalainen-nv jvepsalainen-nv left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is a well-scoped, well-documented fix for a real compile-time regression, and it
was already close to merge-ready. The review found no correctness bug in the shipped
configuration, but one behavioral risk and a cluster of comment-accuracy/structure issues.
All nine findings are addressed in commit fc4ced1 on this branch; the inline comments
below record what changed and why.

Main points

  • The highest-risk finding (C002): the differentiable-interface gate was checked before
    the table-level HLSLExport/KeepAlive rule, so a user-exported or dynamic-dispatch
    conformance table in the differentiable family could silently lose its keep-alive
    guarantee. The fix restores the pre-#9808 rule order. Empirically the builtin
    differentiable tables carry neither decoration, so -dump-ir output across all passes
    is byte-identical for non-differentiating shaders — the perf win is unchanged. The PR
    description's claim that #9808 marks these tables [HLSLExport] (the stated reason for
    the reordering) was not reproducible; the description is worth updating to match.
  • The pruning predicate is now a single named helper
    (IRSharedSpecContext::canPruneAutodiffLinkArtifacts()) carrying the canonical safety
    argument, and the differentiable-interface family has one authoritative definition
    (isDifferentiableInterfaceBuiltin() next to the enum).
  • The invariants the gates rest on are now recorded at their definition sites: a note at
    AnnotationKind, and a contract comment on doesModuleUseAutodiff (including the fact,
    verified by IR dumps, that generic-parameter-dependent fwd_diff requests hoist only to
    the enclosing generic and are invisible to the module-scope scan).

Remaining follow-ups (not blocking)

  • The IRBuiltinRequirementKey carve-out in cloneWitnessTableImpl still clones the
    Differential/dzero/dadd entries eagerly, so pruning is partial; this may be part
    of the remaining simplifyIR regression tracked in #11780.
  • Whether a program whose only auto-diff use is generic-parameter-dependent can slip past
    doesModuleUseAutodiff deserves a dedicated regression test; local probes compile
    correctly, and the contract comment now makes the assumption auditable.

Comment thread source/slang/slang-ir-link.cpp
Comment thread source/slang/slang-ir-link.cpp
Comment thread source/slang/slang-ir-link.cpp Outdated
Comment thread source/slang/slang-type-system-shared.h
Comment thread source/slang/slang-ir-link.cpp
Comment thread source/slang/slang-ir-link.cpp
Comment thread source/slang/slang-ir-link.cpp
Comment thread source/slang/slang-ir-link.cpp
Comment thread source/slang/slang-ast-support-types.h
CI for this PR failed test-slang on every platform. Both failures trace to
the pruning making linked modules genuinely minimal for the first time, which
exposed one bug in this PR's detector and one long-latent pipeline bug that
the ever-present dead auto-diff IR had been masking.

1. doesModuleUseAutodiff missed generic-nested translation requests.
   __fwd_diff(genericFn) lowers to a generic wrapper whose inner value is
   ForwardDifferentiate(specialize(genericFn, T, ...)); the translate inst
   hoists only into that generic, never to module scope, so the module-scope
   scan returned false and the final link pruned annotations that DiffPair
   lowering later needed — the ICE 'Unrecognized field. Cannot emit field
   accessor' in tests/autodiff/no-diff-interface-subscript.slang (cpu).
   The detector is now a full recursive walk (containsTranslateInst), making
   the no-false-negatives contract hold by construction.

2. specializeModule only ran its cleanup group — critically
   unrollLoopsInModule, the ONLY call site that implements [ForceUnroll] /
   [unroll] semantics and diagnoses un-unrollable loops — after an iteration
   that performed specialization. Every module used to contain dead auto-diff
   generics, so the first iteration always specialized something and the
   group always ran; with pruning, a program with no specialization work
   never had its loops unrolled (tests/ir/loop-unroll-simplify,
   tests/language-feature/execution-model/varying-array-input, and the
   obfuscation loc-check tests). The group now runs on every round, and
   unrollLoopsInModule gained an optional outChanged parameter (its return
   value reports success, not change) so unroll-exposed specialization
   opportunities still trigger another round, preserving the old fixpoint
   semantics.

Validation:
- All eight previously failing tests now pass locally (remaining local
  failures are this machine's known-broken slang-llvm backend and
  shader-dll line-directive tests, identical without this change).
- tests/ir, tests/obfuscate, tests/serialization,
  tests/language-feature/execution-model, tests/language-feature/generics,
  tests/diagnostics, and the interpreter auto-diff tests pass.
- Final SPIR-V for non-differentiating probes is byte-identical to the
  previous head; the -dump-ir stream shrinks ~8x (31.6k -> 4.1k lines for an
  empty shader) because the unconditional first-round DCE now removes the
  residual dead IR immediately, strengthening the compile-time win.
github-actions[bot]

This comment was marked as outdated.

unrollLoopsInFunc set *outChanged as soon as collection found [ForceUnroll]
candidates, before any rewrite: an orphaned loop (skipped by the
!loop->parent guard) still reported a change, and the specialize fixpoint
then took a full extra simplification round for nothing. Move the write
after a successful _unrollLoop so the flag means what the header documents.

Also add tests/ir/force-unroll-non-generic-non-diff.slang: a non-generic,
non-differentiating [ForceUnroll] shader that pins the unconditional cleanup
group in the specialize fixpoint — with auto-diff link pruning such a program
has no other reason to iterate, so re-gating unroll on per-round change would
leave its loop rolled.
…g gate

cloneAnnotations' wholesale skip is safe only while every AnnotationKind is
auto-diff-related — an invariant previously guarded by comments alone, the
same silent failure mode that let PR shader-slang#9808 disconnect the original gating.
Add a CountOf sentinel to the enum and a static_assert at the gate so adding
a kind forces the author to revisit the skip.

Also correct the doesModuleUseAutodiff comment: the recursive walk's
necessity is empirical and broad (a module-scope-only scan fails ~240
tests/autodiff/ tests, including an ICE on no-diff-interface-subscript), not
carried by any single cited test.
- link-prune-non-autodiff.slang pins the gate in both directions from one
  source: the non-differentiating variant's IR dump must contain no
  Annotation(...) insts after linking (this fails under the pre-shader-slang#11779
  behavior), and the __fwd_diff variant keeps them, which also guards the
  CHECK-NOT spelling against vacuity.
- module-prelink-keeps-autodiff.slang + diff-library-module.slang pin the
  prelink-vs-final-link distinction: the consumer differentiates a function
  from a precompiled .slang-module (import prefers the binary module), so
  pruning during the prelink that produced it breaks this test.
- fwd-diff-nested-in-generic.slang pins the nested-in-generic translation
  request shape end-to-end (with the where T.Differential == T constraint
  needed to express it).

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: 🟡 Minor gaps — 2 test-coverage gaps, no correctness bugs found

Restores auto-diff link-time pruning under a new isFinalCodegenLink gate applied only in linkIR, and re-runs the specialize-loop cleanup group unconditionally (with unrolling now feeding an outChanged back into the fixpoint). The scope split between prelinkIR (never prune) and linkIR (prune when auto-diff unused) is sound, and the deferred-witness-entry safety argument in the PR body checks out against cloneWitnessTableImpl (mangled-name-keyed entries are pruned; IRBuiltinRequirementKey-keyed entries are still eager-cloned).

Changes Overview

Auto-diff link gating (slang-ir-link.cpp, slang-ast-support-types.h, slang-type-system-shared.h)

  • IRSharedSpecContext::isFinalCodegenLink flag, set true only inside linkIR (never in prelinkIR).
  • canPruneAutodiffLinkArtifacts() = isFinalCodegenLink && !useAutodiff gates both the wholesale early-return in cloneAnnotations and the differentiable-interface branch of shouldDeepCloneWitnessTable, with the keep-alive ([HLSLExport]/COM/DynamicDispatch) rules moved ahead so pruning cannot override them.
  • doesModuleUseAutodiff now recursively walks the entire inst tree via containsTranslateInst (necessary because IRTranslateBase requests can be nested in generics — see the new fwd-diff-nested-in-generic.slang explicit reproducer).
  • AnnotationKind::CountOf = 16 sentinel + static_assert in cloneAnnotations so any new annotation kind forces a visit to the wholesale-skip gate.
  • New isDifferentiableInterfaceBuiltin helper extracts the interface-name switch as the single source of truth.

Specialize fixpoint + loop-unroll wire-up (slang-ir-specialize.cpp, slang-ir-loop-unroll.{cpp,h})

  • The cleanup group (DCE, peephole, mandatory early-inlining, SCCP, unrollLoopsInModule) now runs on every fixpoint iteration, not only after a round that specialized something. Rationale: unrollLoopsInModule implements [ForceUnroll]/[unroll] and is its only pipeline call site.
  • unrollLoopsInFunc/unrollLoopsInModule grow a bool* outChanged output parameter set true only when a loop is actually rewritten; a set flag re-arms iterChanged so the fixpoint takes another round.

Tests (tests/autodiff/*.slang, tests/ir/force-unroll-non-generic-non-diff.slang)

  • link-prune-non-autodiff.slang: PRUNED vs KEPT -dump-ir filecheck of Annotation(.
  • module-prelink-keeps-autodiff.slang + diff-library-module.slang: cross-module precompiled .slang-module prelink retention.
  • fwd-diff-nested-in-generic.slang: minimal explicit reproducer for the recursive-walk requirement.
  • force-unroll-non-generic-non-diff.slang: non-generic, non-diff [ForceUnroll] regression pin for the ungated cleanup group.
Findings (2 total)
Severity Location Finding
🟡 Gap tests/autodiff/module-prelink-keeps-autodiff.slang:24 bwd_diff half of the library-import prelink scenario, and of the nested-in-generic scenario, is untested — both new autodiff tests only exercise __fwd_diff.
🟡 Gap source/slang/slang-ir-specialize.cpp:1741 No test exercises the unrolledAnyLoop → iterChanged = true wire-up; the new force-unroll test cannot fail if that re-arming is removed.

Comment thread tests/autodiff/module-prelink-keeps-autodiff.slang
Comment thread source/slang/slang-ir-specialize.cpp
@jkwak-work

Copy link
Copy Markdown
Collaborator

It looks like we need @saipraveenb25 to review this.

@jvepsalainen-nv jvepsalainen-nv added this pull request to the merge queue Jul 7, 2026
Merged via the queue into shader-slang:master with commit 22d2764 Jul 7, 2026
128 of 130 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr: non-breaking PRs without breaking changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Per-compile linkIR / linkAndOptimizeIR regression since the auto-diff refactor (auto-diff artifacts linked into every program)

4 participants