[clang] [HLSL] Add empty struct test cases to `__builtin_hlsl_is_typed_resource_element_compatible` test file (PR #115045)

Joshua Batista via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 7 12:24:50 PST 2024


https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/115045

>From ef4a7eea3eacce4f77b628aebe7f2838733971d0 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Tue, 5 Nov 2024 10:35:59 -0800
Subject: [PATCH 1/4] add empty struct test cases

---
 .../SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
index acc1f281daddfc..08d75a0c23b228 100644
--- a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
+++ b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
@@ -107,3 +107,5 @@ struct TypeDefTest {
 };
 
 _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(TypeDefTest), "");
+
+

>From 0ed4809a4bb12618e885914c09ba83e44c9c83c9 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Tue, 5 Nov 2024 10:58:58 -0800
Subject: [PATCH 2/4] remove assert, return false instead

---
 clang/lib/Sema/SemaHLSL.cpp                              | 6 ++++--
 .../Types/Traits/IsTypedResourceElementCompatible.hlsl   | 9 +++++++++
 .../Traits/IsTypedResourceElementCompatibleErrors.hlsl   | 1 -
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 298b7ad4f9e687..4b5b5aa96d5c20 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2210,8 +2210,10 @@ bool SemaHLSL::IsTypedResourceElementCompatible(clang::QualType QT) {
   llvm::SmallVector<QualType, 4> QTTypes;
   BuildFlattenedTypeList(QT, QTTypes);
 
-  assert(QTTypes.size() > 0 &&
-         "expected at least one constituent type from non-null type");
+  // empty structs are not typed resource element compatible
+  if (QTTypes.size() == 0)
+    return false;
+
   QualType FirstQT = SemaRef.Context.getCanonicalType(QTTypes[0]);
 
   // element count cannot exceed 4
diff --git a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
index 08d75a0c23b228..0a124be3e0aa60 100644
--- a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
+++ b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
@@ -108,4 +108,13 @@ struct TypeDefTest {
 
 _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(TypeDefTest), "");
 
+struct EmptyStruct {};
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(EmptyStruct), "");
 
+struct EmptyDerived : EmptyStruct {};
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(EmptyDerived), "");
+
+struct EmptyBase : EmptyStruct {
+  int4 V;
+};
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(EmptyBase), ""); 
diff --git a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
index cb3e9ae7a61509..1cc9880e5b25f1 100644
--- a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
+++ b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
@@ -7,4 +7,3 @@ _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(__hlsl_resour
 struct notComplete;
 // expected-error at +1{{incomplete type 'notComplete' where a complete type is required}}
 _Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(notComplete), "");
- 

>From 65c6e1a384dd529a749a2cc8e20aa5a70d17c60b Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Tue, 5 Nov 2024 16:26:23 -0800
Subject: [PATCH 3/4] address chris

---
 clang/lib/Sema/SemaHLSL.cpp                   |  11 +-
 .../IsTypedResourceElementCompatible.hlsl     | 116 ++----------------
 2 files changed, 19 insertions(+), 108 deletions(-)

diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 4b5b5aa96d5c20..b0dd7369749619 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2200,17 +2200,20 @@ static void BuildFlattenedTypeList(QualType BaseTy,
 }
 
 bool SemaHLSL::IsTypedResourceElementCompatible(clang::QualType QT) {
-  if (QT.isNull())
+  // null and array types are not allowed.
+  if (QT.isNull() || QT->isArrayType())
     return false;
 
-  // check if the outer type was an array type
-  if (QT->isArrayType())
+  // UDT types are not allowed
+  clang::QualType CanonicalType = QT.getCanonicalType();
+  if (CanonicalType->getAs<clang::RecordType>()) {
     return false;
+  }
 
   llvm::SmallVector<QualType, 4> QTTypes;
   BuildFlattenedTypeList(QT, QTTypes);
 
-  // empty structs are not typed resource element compatible
+  // empty element type is not typed resource element compatible
   if (QTTypes.size() == 0)
     return false;
 
diff --git a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
index 0a124be3e0aa60..8df9a2c45150cd 100644
--- a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
+++ b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
@@ -1,120 +1,28 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -verify %s
 // expected-no-diagnostics
 
-struct oneInt {
-    int i;
-};
-
-struct twoInt {
-   int aa;
-   int ab;
-};
-
-struct threeInts {
-  oneInt o;
-  twoInt t;
-};
-
-struct oneFloat {
-    float f;
-};
-struct depthDiff {
-  int i;
-  oneInt o;
-  oneFloat f;
-};
-
-struct notHomogenous{     
-  int i;
-  float f;
-};
-
-struct EightElements {
-  twoInt x[2];
-  twoInt y[2];
-};
-
-struct EightHalves {
-half x[8]; 
-};
-
-struct intVec {
-  int2 i;
-};
-
-struct oneIntWithVec {
-  int i;
-  oneInt i2;
-  int2 i3;
-};
-
-struct weirdStruct {
-  int i;
-  intVec iv;
-};
 
 _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(int), "");
 _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(float), "");
 _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(float4), "");
 _Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(double2), "");
-_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(oneInt), "");
-_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(oneFloat), "");
-_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(twoInt), "");
-_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(threeInts), "");
-_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(notHomogenous), "");
-_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(depthDiff), "");
-_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(EightElements), "");
-_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(EightHalves), "");
-_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(oneIntWithVec), "");
-_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(weirdStruct), "");
-_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(RWBuffer<int>), "");
 
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(RWBuffer<int>), "");
 
-// arrays not allowed
-_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(half[4]), "");
-
-template<typename T> struct TemplatedBuffer {
-    T a;
-    __hlsl_resource_t h;
-};
-_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(TemplatedBuffer<int>), "");
-
-struct MyStruct1 : TemplatedBuffer<float> {
-    float x;
-};
-_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(MyStruct1), "");
-
-struct MyStruct2 {
-    const TemplatedBuffer<float> TB[10];
-};
-_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(MyStruct2), "");
-
-template<typename T> struct SimpleTemplate {
-    T a;
-};
-
-// though the element type is incomplete, the type trait should still technically return true
-_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(SimpleTemplate<__hlsl_resource_t>), "");
-
-_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(SimpleTemplate<float>), "");
-
-
-typedef int myInt;
-
-struct TypeDefTest {
+struct s {
     int x;
-    myInt y;
 };
 
-_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(TypeDefTest), "");
+// structs not allowed
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(s), "");
 
-struct EmptyStruct {};
-_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(EmptyStruct), "");
+// arrays not allowed
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(half[4]), "");
 
-struct EmptyDerived : EmptyStruct {};
-_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(EmptyDerived), "");
+typedef vector<int, 8> int8;
+// too many elements
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(int8), "");
+
+// size exceeds 16 bytes, and exceeds element count limit after splitting 64 bit types into 32 bit types
+_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(double3), "");
 
-struct EmptyBase : EmptyStruct {
-  int4 V;
-};
-_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(EmptyBase), ""); 

>From 3456c1419979039fe51c7ac71556e1345ad7b22d Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Thu, 7 Nov 2024 12:24:24 -0800
Subject: [PATCH 4/4] address chris, remove homogeneity check and
 buildFlattenedList call

---
 clang/lib/Sema/SemaHLSL.cpp | 43 +++++++++++++++----------------------
 1 file changed, 17 insertions(+), 26 deletions(-)

diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index b0dd7369749619..b03069001969f7 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2210,42 +2210,33 @@ bool SemaHLSL::IsTypedResourceElementCompatible(clang::QualType QT) {
     return false;
   }
 
-  llvm::SmallVector<QualType, 4> QTTypes;
-  BuildFlattenedTypeList(QT, QTTypes);
-
-  // empty element type is not typed resource element compatible
-  if (QTTypes.size() == 0)
-    return false;
-
-  QualType FirstQT = SemaRef.Context.getCanonicalType(QTTypes[0]);
+  // the only other valid builtin types are scalars or vectors
+  if (const BuiltinType *BT = CanonicalType->getAs<BuiltinType>()) {
+    if (BT->isBooleanType() || BT->isEnumeralType())
+      return false;
 
-  // element count cannot exceed 4
-  if (QTTypes.size() > 4)
-    return false;
+    int TotalSizeInBytes = SemaRef.Context.getTypeSize(BT) / 8;
 
-  for (QualType TempQT : QTTypes) {
-    // ensure homogeneity
-    if (!getASTContext().hasSameUnqualifiedType(FirstQT, TempQT))
+    if (TotalSizeInBytes > 16)
       return false;
+    return true;
   }
 
-  if (const BuiltinType *BT = FirstQT->getAs<BuiltinType>()) {
-    if (BT->isBooleanType() || BT->isEnumeralType())
+  if (const VectorType *VT = CanonicalType->getAs<VectorType>()) {
+    int ArraySize = VT->getNumElements();
+
+    if (ArraySize > 4)
       return false;
 
-    // Check if it is an array type.
-    if (FirstQT->isArrayType())
+    QualType ElTy = VT->getElementType();
+    int TotalSizeInBytes = (SemaRef.Context.getTypeSize(ElTy) / 8) * ArraySize;
+
+    if (TotalSizeInBytes > 16)
       return false;
+    return true;
   }
 
-  // if the loop above completes without returning, then
-  // we've guaranteed homogeneity
-  int TotalSizeInBytes =
-      (SemaRef.Context.getTypeSize(FirstQT) / 8) * QTTypes.size();
-  if (TotalSizeInBytes > 16)
-    return false;
-
-  return true;
+  return false;
 }
 
 bool SemaHLSL::IsScalarizedLayoutCompatible(QualType T1, QualType T2) const {



More information about the cfe-commits mailing list