Skip to content

Commit 1e4181c

Browse files
authored
Fix type annotation serialization for resources in HL modules (#8442)
This broke for -fcgl when adding resource type annotations in DXIL 1.8. It broke because the dx.types.ResourceProperties type was created by the DxilModule DxilOperations class (hlsl::OP), and the code tried to get this class from the DxilModule, which was nullptr because it was serializing an HLModule, not a DxilModule. The fix moves dx.types.ResourceProperties type creation to hlsl::resource_helper, which is where it seems to fit best. The local member and accessor in hlsl::OP is left as this will cache the type, as it did before, instead of looking it up by name frequently for each dxil op. Only the initialization of the hlsl::OP member is changed to use the resource_helper function instead. Fixes #8440
1 parent 3bb9bee commit 1e4181c

6 files changed

Lines changed: 126 additions & 5 deletions

File tree

include/dxc/DXIL/DxilResourceProperties.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
namespace llvm {
1717
class Constant;
1818
class Type;
19+
class Module;
1920
} // namespace llvm
2021

2122
namespace hlsl {
@@ -89,6 +90,7 @@ struct DxilInst_AnnotateHandle;
8990
namespace resource_helper {
9091
llvm::Constant *getAsConstant(const DxilResourceProperties &, llvm::Type *Ty,
9192
const ShaderModel &);
93+
llvm::Type *GetResourcePropertiesType(llvm::Module &M);
9294
DxilResourceProperties loadPropsFromConstant(const llvm::Constant &C);
9395
DxilResourceProperties
9496
loadPropsFromAnnotateHandle(DxilInst_AnnotateHandle &annotateHandle,

lib/DXIL/DxilMetadataHelper.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,8 +1345,7 @@ Metadata *DxilMDHelper::EmitDxilFieldAnnotation(const DxilFieldAnnotation &FA) {
13451345
MDVals.emplace_back(Uint32ToConstMD(kDxilFieldAnnotationResPropTag));
13461346
MDVals.emplace_back(ValueAsMetadata::get(resource_helper::getAsConstant(
13471347
FA.GetResourceProperties(),
1348-
m_pModule->GetDxilModule().GetOP()->GetResourcePropertiesType(),
1349-
*m_pSM)));
1348+
resource_helper::GetResourcePropertiesType(*m_pModule), *m_pSM)));
13501349
}
13511350
if (DXIL::CompareVersions(m_MinValMajor, m_MinValMinor, 1, 7) >= 0) {
13521351
if (FA.HasBitFields()) {

lib/DXIL/DxilOperations.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4118,9 +4118,8 @@ OP::OP(LLVMContext &Ctx, Module *pModule)
41184118
"dx.types.NodeHandle", pModule);
41194119
m_pNodeRecordHandleType = GetOrCreateStructType(
41204120
m_Ctx, Type::getInt8PtrTy(m_Ctx), "dx.types.NodeRecordHandle", pModule);
4121-
m_pResourcePropertiesType = GetOrCreateStructType(
4122-
m_Ctx, {Type::getInt32Ty(m_Ctx), Type::getInt32Ty(m_Ctx)},
4123-
"dx.types.ResourceProperties", pModule);
4121+
m_pResourcePropertiesType =
4122+
hlsl::resource_helper::GetResourcePropertiesType(*pModule);
41244123
m_pNodePropertiesType = GetOrCreateStructType(
41254124
m_Ctx, {Type::getInt32Ty(m_Ctx), Type::getInt32Ty(m_Ctx)},
41264125
"dx.types.NodeInfo", pModule);

lib/DXIL/DxilResourceProperties.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/IR/Constant.h"
2020
#include "llvm/IR/Constants.h"
2121
#include "llvm/IR/DerivedTypes.h"
22+
#include "llvm/IR/Module.h"
2223

2324
using namespace llvm;
2425

@@ -104,6 +105,17 @@ Constant *getAsConstant(const DxilResourceProperties &RP, Type *Ty,
104105
return nullptr;
105106
}
106107

108+
llvm::Type *GetResourcePropertiesType(Module &M) {
109+
LLVMContext &Ctx = M.getContext();
110+
StringRef Name = "dx.types.ResourceProperties";
111+
if (StructType *ST = M.getTypeByName(Name))
112+
return ST;
113+
114+
Type *Int32Ty = Type::getInt32Ty(Ctx);
115+
Type *Elements[] = {Int32Ty, Int32Ty};
116+
return StructType::create(Ctx, Elements, Name);
117+
}
118+
107119
DxilResourceProperties loadPropsFromConstant(const Constant &C) {
108120
DxilResourceProperties RP;
109121

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// REQUIRES: dxil-1-8
2+
// RUN: %dxc -T cs_6_8 -fcgl %s | FileCheck %s
3+
4+
// CHECK: %dx.types.ResourceProperties = type { i32, i32 }
5+
// CHECK: !dx.typeAnnotations = !{![[TYPE_ANNOTATIONS:[0-9]+]]}
6+
// CHECK: ![[TYPE_ANNOTATIONS]] = !{
7+
// CHECK-SAME: void (%struct.RWByteAddressBuffer*)* @"\01?foo@@YAXURWByteAddressBuffer@@@Z", ![[FN_ANN:[0-9]+]]
8+
// CHECK: ![[FN_ANN]] = !{!{{[0-9]+}}, ![[PARAM_ANN:[0-9]+]]}
9+
// CHECK: ![[PARAM_ANN]] = !{i32 0, ![[FIELD_ANN:[0-9]+]], !{{[0-9]+}}}
10+
// CHECK: ![[FIELD_ANN]] = !{
11+
// CHECK-SAME: i32 10, %dx.types.ResourceProperties { i32 4107, i32 0 }
12+
13+
RWByteAddressBuffer OutBuff : register(u0);
14+
15+
void foo(RWByteAddressBuffer Buf) {
16+
Buf.Store(0, 42);
17+
}
18+
19+
[numthreads(8, 1, 1)]
20+
void main() {
21+
foo(OutBuff);
22+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
; RUN: %dxopt %s -hlsl-passes-resume -hlsl-passes-pause -S | FileCheck %s
2+
3+
; Test round-trip metadata serialization for ResourceProperties type annotation.
4+
5+
; CHECK: %dx.types.ResourceProperties = type { i32, i32 }
6+
; CHECK: !dx.typeAnnotations = !{![[TYPE_ANNOTATIONS:[0-9]+]]}
7+
; CHECK: ![[TYPE_ANNOTATIONS]] = !{
8+
; CHECK-SAME: void (%struct.RWByteAddressBuffer*)* @"\01?foo@@YAXURWByteAddressBuffer@@@Z", ![[FN_ANN:[0-9]+]]
9+
; CHECK: ![[FN_ANN]] = !{!{{[0-9]+}}, ![[PARAM_ANN:[0-9]+]]}
10+
; CHECK: ![[PARAM_ANN]] = !{i32 0, ![[FIELD_ANN:[0-9]+]], !{{[0-9]+}}}
11+
; CHECK: ![[FIELD_ANN]] = !{
12+
; CHECK-SAME: i32 10, %dx.types.ResourceProperties { i32 4107, i32 0 }
13+
14+
target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
15+
target triple = "dxil-ms-dx"
16+
17+
%struct.RWByteAddressBuffer = type { i32 }
18+
%ConstantBuffer = type opaque
19+
%dx.types.Handle = type { i8* }
20+
%dx.types.ResourceProperties = type { i32, i32 }
21+
22+
@"\01?OutBuff@@3URWByteAddressBuffer@@A" = external global %struct.RWByteAddressBuffer, align 4
23+
@"$Globals" = external constant %ConstantBuffer
24+
25+
; Function Attrs: nounwind
26+
define void @main() #0 {
27+
entry:
28+
call void @"\01?foo@@YAXURWByteAddressBuffer@@@Z"(%struct.RWByteAddressBuffer* @"\01?OutBuff@@3URWByteAddressBuffer@@A")
29+
ret void
30+
}
31+
32+
; Function Attrs: alwaysinline nounwind
33+
define internal void @"\01?foo@@YAXURWByteAddressBuffer@@@Z"(%struct.RWByteAddressBuffer* %Buf) #1 {
34+
entry:
35+
%0 = load %struct.RWByteAddressBuffer, %struct.RWByteAddressBuffer* %Buf
36+
%1 = call %dx.types.Handle @"dx.hl.createhandle..%dx.types.Handle (i32, %struct.RWByteAddressBuffer)"(i32 0, %struct.RWByteAddressBuffer %0)
37+
%2 = call %dx.types.Handle @"dx.hl.annotatehandle..%dx.types.Handle (i32, %dx.types.Handle, %dx.types.ResourceProperties, %struct.RWByteAddressBuffer)"(i32 14, %dx.types.Handle %1, %dx.types.ResourceProperties { i32 4107, i32 0 }, %struct.RWByteAddressBuffer undef)
38+
call void @"dx.hl.op..void (i32, %dx.types.Handle, i32, i32)"(i32 277, %dx.types.Handle %2, i32 0, i32 42)
39+
ret void
40+
}
41+
42+
; Function Attrs: nounwind
43+
declare void @"dx.hl.op..void (i32, %dx.types.Handle, i32, i32)"(i32, %dx.types.Handle, i32, i32) #0
44+
45+
; Function Attrs: nounwind readnone
46+
declare %dx.types.Handle @"dx.hl.createhandle..%dx.types.Handle (i32, %struct.RWByteAddressBuffer)"(i32, %struct.RWByteAddressBuffer) #2
47+
48+
; Function Attrs: nounwind readnone
49+
declare %dx.types.Handle @"dx.hl.annotatehandle..%dx.types.Handle (i32, %dx.types.Handle, %dx.types.ResourceProperties, %struct.RWByteAddressBuffer)"(i32, %dx.types.Handle, %dx.types.ResourceProperties, %struct.RWByteAddressBuffer) #2
50+
51+
attributes #0 = { nounwind }
52+
attributes #1 = { alwaysinline nounwind }
53+
attributes #2 = { nounwind readnone }
54+
55+
!llvm.module.flags = !{!0}
56+
!pauseresume = !{!1}
57+
!llvm.ident = !{!2}
58+
!dx.version = !{!3}
59+
!dx.valver = !{!4}
60+
!dx.shaderModel = !{!5}
61+
!dx.typeAnnotations = !{!6}
62+
!dx.entryPoints = !{!13}
63+
!dx.fnprops = !{!19}
64+
!dx.options = !{!20, !21}
65+
66+
!0 = !{i32 2, !"Debug Info Version", i32 3}
67+
!1 = !{!"hlsl-hlemit", !"hlsl-hlensure"}
68+
!2 = !{!"dxc(private) 1.9.0.15350 (main, 348fc7832)"}
69+
!3 = !{i32 1, i32 8}
70+
!4 = !{i32 1, i32 10}
71+
!5 = !{!"cs", i32 6, i32 8}
72+
!6 = !{i32 1, void ()* @main, !7, void (%struct.RWByteAddressBuffer*)* @"\01?foo@@YAXURWByteAddressBuffer@@@Z", !10}
73+
!7 = !{!8}
74+
!8 = !{i32 1, !9, !9}
75+
!9 = !{}
76+
!10 = !{!8, !11}
77+
!11 = !{i32 0, !12, !9}
78+
!12 = !{i32 10, %dx.types.ResourceProperties { i32 4107, i32 0 }}
79+
!13 = !{void ()* @main, !"main", null, !14, null}
80+
!14 = !{null, !15, !17, null}
81+
!15 = !{!16}
82+
!16 = !{i32 0, %struct.RWByteAddressBuffer* @"\01?OutBuff@@3URWByteAddressBuffer@@A", !"OutBuff", i32 0, i32 0, i32 1, i32 11, i1 false, i1 false, i1 false, null}
83+
!17 = !{!18}
84+
!18 = !{i32 0, %ConstantBuffer* @"$Globals", !"$Globals", i32 0, i32 -1, i32 1, i32 0, null}
85+
!19 = !{void ()* @main, i32 5, i32 8, i32 1, i32 1}
86+
!20 = !{i32 64}
87+
!21 = !{i32 -1}

0 commit comments

Comments
 (0)