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

Đang mở Phù hợp với người mới
#9,015 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
78/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
cpp
Lĩnh vực
backend

Hướng nghiên cứu

Bắt đầu tại lib/HLSL/DxilLinker.cpp, ở hai vị trí tạo module mới có thiết lập target triple, rồi so sánh thiết lập của module đã liên kết với module gốc. Đọc lib/HLSL/DxilContainerReflection.cpp để xem cách lấy offset của các thành viên struct, sau đó chạy bản tái hiện độc lập đính kèm và so sánh reflection của thư viện với reflection sau khi liên kết. Hoàn tất khi reflection của module đã liên kết báo kích thước 16 và offset thành viên là 0 và 8 cho WithU64, khớp với thư viện.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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)
Ngôn ngữ chính
C++
Star
3.7k
Fork
914
Merge trung bình
2 ngày 20 giờ
Pull request đã merge (30 ngày)
20

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của microsoft/DirectXShaderCompiler

Tất cả issue của microsoft/DirectXShaderCompiler

Issue tương tự

Thêm issue về C++

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.