Skip to content

Commit d013457

Browse files
authored
[SM6.10] Make DxilStructAnnotation aware of target types (#8282)
Update `DxilStructAnnotation` to be aware of target types. Otherwise the annotation would declare a struct with a single LinAlg Matrix type as empty, leading to invalid codegen. Declaration names match the style of the surrounding code. Fixes #8279
1 parent 6ea7cf1 commit d013457

4 files changed

Lines changed: 82 additions & 11 deletions

File tree

include/dxc/DXIL/DxilTypeSystem.h

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,12 @@ class DxilStructAnnotation {
148148
void SetCBufferSize(unsigned size);
149149
void MarkEmptyStruct();
150150
bool IsEmptyStruct();
151-
// Since resources don't take real space, IsEmptyBesidesResources
152-
// determines if the structure is empty or contains only resources.
153-
bool IsEmptyBesidesResources();
151+
// Since resources and target types don't take real space,
152+
// IsEmptyBesidesResourcesAndTargetTypes() determines if the structure is
153+
// empty or contains only resources or target types.
154+
bool IsEmptyBesidesResourcesAndTargetTypes() const;
154155
bool ContainsResources() const;
156+
bool ContainsTargetTypes() const;
155157

156158
// For template args, GetNumTemplateArgs() will return 0 if not a template
157159
unsigned GetNumTemplateArgs() const;
@@ -174,6 +176,15 @@ class DxilStructAnnotation {
174176
False,
175177
Only
176178
} m_ResourcesContained = HasResources::False;
179+
180+
void SetContainsTargetTypes();
181+
// HasTargetTypes::Only will be set on MarkEmptyStruct() when
182+
// HasTargetTypes::True
183+
enum class HasTargetTypes {
184+
True,
185+
False,
186+
Only
187+
} m_TargetTypesContained = HasTargetTypes::False;
177188
};
178189

179190
/// Use this class to represent type annotation for DXR payload field.
@@ -341,7 +352,10 @@ class DxilTypeSystem {
341352
void SetMinPrecision(bool bMinPrecision);
342353

343354
// Determines whether type is a resource or contains a resource
344-
bool IsResourceContained(llvm::Type *Ty);
355+
bool IsResourceContained(llvm::Type *Ty) const;
356+
357+
// Determines whether type is a target type or contains a target type
358+
bool IsTargetTypeContained(llvm::Type *Ty) const;
345359

346360
private:
347361
llvm::Module *m_pModule;

lib/DXIL/DxilTypeSystem.cpp

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,14 +236,17 @@ void DxilStructAnnotation::SetCBufferSize(unsigned size) {
236236
void DxilStructAnnotation::MarkEmptyStruct() {
237237
if (m_ResourcesContained == HasResources::True)
238238
m_ResourcesContained = HasResources::Only;
239+
else if (m_TargetTypesContained == HasTargetTypes::True)
240+
m_TargetTypesContained = HasTargetTypes::Only;
239241
else
240242
m_FieldAnnotations.clear();
241243
}
242244
bool DxilStructAnnotation::IsEmptyStruct() {
243245
return m_FieldAnnotations.empty();
244246
}
245-
bool DxilStructAnnotation::IsEmptyBesidesResources() {
247+
bool DxilStructAnnotation::IsEmptyBesidesResourcesAndTargetTypes() const {
246248
return m_ResourcesContained == HasResources::Only ||
249+
m_TargetTypesContained == HasTargetTypes::Only ||
247250
m_FieldAnnotations.empty();
248251
}
249252

@@ -256,6 +259,14 @@ bool DxilStructAnnotation::ContainsResources() const {
256259
return m_ResourcesContained != HasResources::False;
257260
}
258261

262+
void DxilStructAnnotation::SetContainsTargetTypes() {
263+
if (m_TargetTypesContained == HasTargetTypes::False)
264+
m_TargetTypesContained = HasTargetTypes::True;
265+
}
266+
bool DxilStructAnnotation::ContainsTargetTypes() const {
267+
return m_TargetTypesContained != HasTargetTypes::False;
268+
}
269+
259270
// For template args, GetNumTemplateArgs() will return 0 if not a template
260271
unsigned DxilStructAnnotation::GetNumTemplateArgs() const {
261272
return (unsigned)m_TemplateAnnotations.size();
@@ -393,6 +404,13 @@ void DxilTypeSystem::FinishStructAnnotation(DxilStructAnnotation &SA) {
393404
SA.SetContainsResources();
394405
}
395406

407+
// Update target type containment
408+
for (unsigned i = 0; i < SA.GetNumFields() && !SA.ContainsTargetTypes();
409+
i++) {
410+
if (IsTargetTypeContained(ST->getElementType(i)))
411+
SA.SetContainsTargetTypes();
412+
}
413+
396414
// Mark if empty
397415
if (SA.GetCBufferSize() == 0)
398416
SA.MarkEmptyStruct();
@@ -854,20 +872,36 @@ void DxilTypeSystem::SetMinPrecision(bool bMinPrecision) {
854872
m_LowPrecisionMode = mode;
855873
}
856874

857-
bool DxilTypeSystem::IsResourceContained(llvm::Type *Ty) {
875+
bool DxilTypeSystem::IsResourceContained(llvm::Type *Ty) const {
858876
// strip pointer/array
859877
if (Ty->isPointerTy())
860878
Ty = Ty->getPointerElementType();
861879
if (Ty->isArrayTy())
862880
Ty = Ty->getArrayElementType();
863881

864-
if (auto ST = dyn_cast<StructType>(Ty)) {
865-
if (dxilutil::IsHLSLResourceType(Ty)) {
882+
if (auto *ST = dyn_cast<StructType>(Ty)) {
883+
if (dxilutil::IsHLSLResourceType(Ty))
866884
return true;
867-
} else if (auto SA = GetStructAnnotation(ST)) {
885+
else if (auto *SA = GetStructAnnotation(ST))
868886
if (SA->ContainsResources())
869887
return true;
870-
}
888+
}
889+
return false;
890+
}
891+
892+
bool DxilTypeSystem::IsTargetTypeContained(llvm::Type *Ty) const {
893+
// strip pointer/array
894+
if (Ty->isPointerTy())
895+
Ty = Ty->getPointerElementType();
896+
if (Ty->isArrayTy())
897+
Ty = Ty->getArrayElementType();
898+
899+
if (auto *ST = dyn_cast<StructType>(Ty)) {
900+
if (dxilutil::IsHLSLKnownTargetType(Ty))
901+
return true;
902+
else if (auto *SA = GetStructAnnotation(ST))
903+
if (SA->ContainsTargetTypes())
904+
return true;
871905
}
872906
return false;
873907
}

lib/HLSL/DxilContainerReflection.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1278,7 +1278,8 @@ HRESULT CShaderReflectionType::Initialize(
12781278

12791279
// There is no annotation for empty structs
12801280
unsigned int fieldCount = 0;
1281-
if (structAnnotation && !structAnnotation->IsEmptyBesidesResources())
1281+
if (structAnnotation &&
1282+
!structAnnotation->IsEmptyBesidesResourcesAndTargetTypes())
12821283
fieldCount = type->getStructNumElements();
12831284

12841285
// The DXBC reflection info computes `Columns` for a
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// REQUIRES: dxil-1-10
2+
// RUN: %dxc -T cs_6_10 -enable-16bit-types %s | FileCheck %s
3+
4+
using MyHandleT = __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(9, 4, 4, 0, 1)]];
5+
6+
class MyMatrix {
7+
MyHandleT handle;
8+
9+
static MyMatrix Splat(float Val) {
10+
MyMatrix Result;
11+
__builtin_LinAlg_FillMatrix(Result.handle, Val);
12+
return Result;
13+
}
14+
};
15+
16+
[numthreads(4, 4, 4)]
17+
void main() {
18+
MyMatrix MatA = MyMatrix::Splat(1.0f);
19+
}
20+
21+
// CHECK: call %dx.types.LinAlgMatrixC9M4N4U0S1 @dx.op.linAlgFillMatrix.mC9M4N4U0S1.f32(i32 -2147483636, float 1.000000e+00) ; LinAlgFillMatrix(value)
22+
// CHECK-NOT: @llvm.trap()

0 commit comments

Comments
 (0)