Skip to content

Fix missing inlinedAt on localized global debug info - #9052

Open
Marijn Suijten (MarijnS95) wants to merge 2 commits into
microsoft:mainfrom
MarijnS95:static-global-inlinedat
Open

Marijn Suijten (MarijnS95) wants to merge 2 commits into
microsoft:mainfrom
MarijnS95:static-global-inlinedat

Conversation

@MarijnS95

@MarijnS95 Marijn Suijten (MarijnS95) commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Since #7799, PatchDebugInfo() creates a dbg.declare for every subprogram on the inlined-at chain of a localized static global's users, but builds each location with only the global's line and that subprogram as scope, without the inlinedAt it was inlined at. Every such declare in an inlined scope therefore points at a different subprogram than the function holding it, and later passes copy that location onto the dbg.value and dx.op.annotateHandle instructions derived from it. The LLVM verifier rejects the result with !dbg attachment points at wrong subprogram for function; drivers that verify the module (e.g. when linking ray tracing libraries into a state object) print that for every static global read in an inlined function.

This collects each subprogram together with its inlinedAt location and gives every declare that chain. A subprogram inlined at several call sites keeps one variable, with one declare per inlined instance.

Those declares share a variable and only differ in their inlinedAt, which LdStHasDebugValue() and DxilDeleteRedundantDebugValues ignored when deduplicating debug values, dropping all but one inlined instance's value. Both now compare the inlinedAt too.

The new test fails without any one of these changes. It deliberately does not pin which subprogram the annotateHandle location is scoped to, because that currently depends on heap layout; #8899 fixes that ordering.

Fixes #8592

🤖 Generated with Claude Code

Since microsoft#7799, PatchDebugInfo() creates a DILocalVariable and dbg.declare
for every subprogram on the inlined-at chain of a localized global's
users. The declare's location is built from just the global's line and
that subprogram as scope, without the inlinedAt the subprogram was
inlined at. For any subprogram other than the function itself, that
location points at a different subprogram than the function holding
the declare, which the LLVM verifier rejects:

  !dbg attachment points at wrong subprogram for function

Later passes propagate the location from those declares onto the
dbg.value and dx.op.annotateHandle instructions that replace them, so
DXIL with -Zi carries these broken locations for every static global
read in an inlined function. Drivers that verify the module, e.g. when
linking ray tracing libraries into a state object, print the error for
each one.

Collect each subprogram together with the location it is inlined at,
and give every declare that inlinedAt. A subprogram inlined at several
call sites keeps a single variable with one declare per inlined
instance, rather than a duplicate variable per call site.

Fixes microsoft#8592

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 20, 2026 09:06
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Marijn Suijten (MarijnS95) added a commit to Traverse-Research/dxc-build that referenced this pull request Oct 20, 2026
Traverse-Research/DirectXShaderCompiler@49b2b00ff backports
microsoft/DirectXShaderCompiler#9052, which gives
the debug info that LowerStaticGlobalIntoAlloca creates for static
globals in inlined scopes its inlinedAt chain. Without it every static
global read in an inlined function carries a !dbg location pointing at
the wrong subprogram, and drivers that verify the module flood stderr
with "!dbg attachment points at wrong subprogram for function".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI 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.

🟡 Changes recommended

Downstream deduplication still drops distinct inline-instance debug bindings, and release-note coverage needs confirmation.

2 open issues
What changed in this PR

Fixes missing inline-call chains in debug information for localized globals, addressing the verifier failures reported in #8592.

Changes:

  • Preserves inlinedAt chains while sharing variable metadata across inline instances.
  • Adds regression coverage for localized globals and sampler annotations.
File Description
tools/​clang/​test/​HLSLFileCheck/​dxil/​debug/​local_global_inlined_at.hlsl Checks inline locations on emitted debug information.
lib/​Transforms/​Scalar/​ScalarReplAggregatesHLSL.cpp Creates declarations with per-instance inline chains.

Review effort: Balanced

Comment on lines +6808 to +6809
DebugLoc Loc =
DebugLoc::get(DGV->getLine(), 0, Scope, SubprogramAndInlinedAt.second);

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.

Added a Bug Fixes entry under Upcoming Release in cf6a7fd.

Comment on lines +6811 to +6815
DILocalVariable *&ConvertedLocalVar =
LocalVars[SubprogramAndInlinedAt.first];
if (!ConvertedLocalVar)
ConvertedLocalVar = DIB.createLocalVariable(
Tag, Scope, Name, DGV->getFile(), DGV->getLine(), Ty);

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.

Confirmed: with two call sites only one inlined instance kept its dbg.value, at both -O3 and -Od. Not a regression from this PR (before it, the second call site had no declare at all), but cheap to fix here: cf6a7fd includes the inlinedAt in both LdStHasDebugValue() and DxilDeleteRedundantDebugValues, and the test now has a second call site. It fails without either of the two changes.

The declares PatchDebugInfo() creates for a subprogram inlined at
several call sites share one variable and only differ in their
inlinedAt. Two passes deduplicating debug values ignored that, and
dropped all but one inlined instance's value:

- LdStHasDebugValue() skips inserting a dbg.value for a store or load
  when the instruction right before it is already a dbg.value of the
  same variable, which is exactly where the previous declare put its.
- DxilDeleteRedundantDebugValues erases a dbg.value when another one
  for the same variable and expression follows it.

Include the inlinedAt in both comparisons, and add a second call site
to the test, which fails without either change.

Also add a release note for microsoft#8592.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 20, 2026 09:21

Copilot AI 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.

🟢 Approval recommended

Inline-chain propagation and deduplication changes are consistent, with focused regression coverage and no identified blocking issues.

2 open issues

Review effort: Balanced

Marijn Suijten (MarijnS95) added a commit to Traverse-Research/dxc-build that referenced this pull request Oct 20, 2026
Traverse-Research/DirectXShaderCompiler@51ea9903d backports
microsoft/DirectXShaderCompiler#9052, which gives
the debug info that LowerStaticGlobalIntoAlloca creates for static
globals in inlined scopes its inlinedAt chain, and keeps a debug value
for every inlined instance of such a global. Without it every static
global read in an inlined function carries a !dbg location pointing at
the wrong subprogram, and drivers that verify the module flood stderr
with "!dbg attachment points at wrong subprogram for function".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@damyanp

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@damyanp

Copy link
Copy Markdown
Member

hby (@hbystuff) - wondering if you'd be able to give this a review please?

@MarijnS95

Copy link
Copy Markdown
Contributor Author

Thanks Damyan Pepper (@damyanp)! Would you also be able to recommend a reviewer/merger for #8899, which addresses another regression we encountered during this DXC upgrade?

This branch has not been deployed

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

Labels

None yet

Projects

Status: New

Development

Successfully merging this pull request may close these issues.

dxil missing inlineAt in debug info for sampler annotations

3 participants