[clang] 4894c67 - [HLSL] add IsTypedResourceElementCompatible type trait (#113730)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 4 10:32:03 PST 2024
Author: Joshua Batista
Date: 2024-11-04T10:31:58-08:00
New Revision: 4894c67230135c8cb177c0bff45a99c8bf09cefe
URL: https://github.com/llvm/llvm-project/commit/4894c67230135c8cb177c0bff45a99c8bf09cefe
DIFF: https://github.com/llvm/llvm-project/commit/4894c67230135c8cb177c0bff45a99c8bf09cefe.diff
LOG: [HLSL] add IsTypedResourceElementCompatible type trait (#113730)
This PR implements a new type trait as a builtin,
`__builtin_hlsl_is_typed_resource_element_compatible`
This type traits verifies that the given input type is suitable as a
typed resource element type.
It checks that the given input type is homogeneous, has no more than 4
sub elements, does not exceed 16 bytes, and does not contain any arrays,
booleans, or enums.
Fixes #113223
Added:
clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
Modified:
clang/include/clang/Basic/TokenKinds.def
clang/include/clang/Sema/SemaHLSL.h
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaHLSL.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index fdfb35de9cf287..2c692c999bdff5 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -662,6 +662,7 @@ KEYWORD(out , KEYHLSL)
// HLSL Type traits
TYPE_TRAIT_2(__builtin_hlsl_is_scalarized_layout_compatible, IsScalarizedLayoutCompatible, KEYHLSL)
TYPE_TRAIT_1(__builtin_hlsl_is_intangible, IsIntangibleType, KEYHLSL)
+TYPE_TRAIT_1(__builtin_hlsl_is_typed_resource_element_compatible, IsTypedResourceElementCompatible, KEYHLSL)
// OpenMP Type Traits
UNARY_EXPR_OR_TYPE_TRAIT(__builtin_omp_required_simd_align, OpenMPRequiredSimdAlign, KEYALL)
diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h
index e30acd87f77218..06c541dec08cc8 100644
--- a/clang/include/clang/Sema/SemaHLSL.h
+++ b/clang/include/clang/Sema/SemaHLSL.h
@@ -132,6 +132,7 @@ class SemaHLSL : public SemaBase {
// HLSL Type trait implementations
bool IsScalarizedLayoutCompatible(QualType T1, QualType T2) const;
+ bool IsTypedResourceElementCompatible(QualType T1);
bool CheckCompatibleParameterABI(FunctionDecl *New, FunctionDecl *Old);
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 50c1b24fce6da7..0001e343da84be 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5032,6 +5032,7 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT,
case UTT_IsScalar:
case UTT_IsCompound:
case UTT_IsMemberPointer:
+ case UTT_IsTypedResourceElementCompatible:
// Fall-through
// These traits are modeled on type predicates in C++0x [meta.unary.prop]
@@ -5714,6 +5715,15 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
tok::kw___builtin_hlsl_is_intangible))
return false;
return T->isHLSLIntangibleType();
+
+ case UTT_IsTypedResourceElementCompatible:
+ assert(Self.getLangOpts().HLSL &&
+ "line vector layout compatible types are HLSL-only feature");
+ if (Self.RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), T,
+ diag::err_incomplete_type))
+ return false;
+
+ return Self.HLSL().IsTypedResourceElementCompatible(T);
}
}
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index a472538236e2d9..e5eb75765383c0 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2199,6 +2199,51 @@ static void BuildFlattenedTypeList(QualType BaseTy,
}
}
+bool SemaHLSL::IsTypedResourceElementCompatible(clang::QualType QT) {
+ if (QT.isNull())
+ return false;
+
+ // check if the outer type was an array type
+ if (QT->isArrayType())
+ return false;
+
+ llvm::SmallVector<QualType, 4> QTTypes;
+ BuildFlattenedTypeList(QT, QTTypes);
+
+ assert(QTTypes.size() > 0 &&
+ "expected at least one constituent type from non-null type");
+ QualType FirstQT = QTTypes[0];
+
+ // element count cannot exceed 4
+ if (QTTypes.size() > 4)
+ return false;
+
+ for (QualType TempQT : QTTypes) {
+ // ensure homogeneity
+ if (TempQT != FirstQT)
+ return false;
+
+ if (const BuiltinType *BT = TempQT->getAs<BuiltinType>()) {
+ if (BT->getKind() == BuiltinType::Bool ||
+ BT->getKind() == BuiltinType::Enum)
+ return false;
+
+ // Check if it is an array type.
+ if (TempQT->isArrayType())
+ return false;
+ }
+ }
+
+ // 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;
+}
+
bool SemaHLSL::IsScalarizedLayoutCompatible(QualType T1, QualType T2) const {
if (T1.isNull() || T2.isNull())
return false;
diff --git a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
new file mode 100644
index 00000000000000..669c03ea39c8f7
--- /dev/null
+++ b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl
@@ -0,0 +1,101 @@
+// 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>), "");
+
+
+// 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>), "");
+
+
diff --git a/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
new file mode 100644
index 00000000000000..167a5be6e93843
--- /dev/null
+++ b/clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatibleErrors.hlsl
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -fnative-half-type -verify %s
+
+// types must be complete
+_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(__hlsl_resource_t), "");
+
+// expected-note at +1{{forward declaration of 'notComplete'}}
+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), "");
+
More information about the cfe-commits
mailing list