IDxcLinker doesn't copy the module data layout, so reflection of linked StructuredBuffer elements misplaces 64-bit integer members

未关闭 适合新手
#9,015 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
78/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
cpp
领域
backend

调研方向

从lib/HLSL/DxilLinker.cpp中设置目标三元组的两个新模块创建位置开始,将链接后模块的设置与原始模块进行比较。阅读lib/HLSL/DxilContainerReflection.cpp,了解如何获取结构体成员偏移量,然后运行附带的独立复现程序,并比较库反射与链接后的反射。完成标准是:链接后WithU64的反射报告大小为16,成员偏移量为0和8,与库一致。

由索引模型根据 Issue 内容生成。

描述

bug needs-triage

Description
DxilLinker creates the linked module and copies only the target triple, never the data layout (lib/HLSL/DxilLinker.cpp, the two "Create new module" / setTargetTriple sites). Reflection of a non-cbuffer struct reads member offsets from Module::getDataLayout().getStructLayout() (lib/HLSL/DxilContainerReflection.cpp). On a linked module that falls back to LLVM's default layout, where i64 is 4-byte aligned. A uint64_t member of a StructuredBuffer element therefore moves from offset 8 to 4, and the element size shrinks from 16 to 12.

double is unaffected, because f64:64 is also in LLVM's default layout. The generated code is correct either way; only the reflection is wrong, and an application that sizes or fills buffers from reflection will get it wrong.

Related: the linker also drops other module state, see #5197 (resource type annotations), #5703 (RDAT) and the cbuffer reflection issue I'm filing alongside this one.

Steps to Reproduce
Full standalone repro attached (repro_linker_datalayout.cpp).

  1. Compile with -T lib_6_3 -Zi -Qembed_debug (-Zi keeps the member types; the element size is wrong without it too):
struct WithU64 { float a; uint64_t b; };
struct WithF64 { float a; double b; };
StructuredBuffer<WithU64> sbU64;
StructuredBuffer<WithF64> sbF64;
RWByteAddressBuffer o;
[shader("compute")]
[numthreads(1, 1, 1)]
void main(uint id : SV_DispatchThreadID) { o.Store<uint>(0, (uint) sbU64[id].b + (uint) sbF64[id].b); }
  1. IDxcLinker::RegisterLibrary(L"lib", lib), then Link(L"main", L"cs_6_3", ...).
  2. Reflect the library (ID3D12LibraryReflection) and the linked shader (ID3D12ShaderReflection). For each buffer, compare D3D12_SHADER_BUFFER_DESC.Size and the element type's member offsets.

Actual Behavior

Expected for both buffers: element size 16, a at 0, b at 8

  lib     sbU64  element size 16, members at a@0 b@8
  linked  sbU64  element size 12, members at a@0 b@4

  lib     sbF64  element size 16, members at a@0 b@8
  linked  sbF64  element size 16, members at a@0 b@8

Environment

  • DXC version: <latest release, from dxc --version>; also reproduces on main, libdxcompiler.so: 1.11(5563-75fba619)(1.10.0.15563)
  • Host Operating System: Windows (release); Linux x86_64 (main)
主要语言
C++
星标
3.7k
派生
914
平均合并
3 天 23 小时
30 天内合并 PR
21

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

microsoft/DirectXShaderCompiler 的其他 Issue

查看 microsoft/DirectXShaderCompiler 的全部 Issue

相似的 Issue

更多 C++ Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。