Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HLSL] Add empty struct test cases to __builtin_hlsl_is_typed_resource_element_compatible test file #115045

Merged
merged 7 commits into from
Nov 15, 2024

Conversation

bob80905
Copy link
Contributor

@bob80905 bob80905 commented Nov 5, 2024

This PR adds empty struct cases to the test file for the builtin.

@llvmbot llvmbot added clang Clang issues not falling into any other category HLSL HLSL Language Support labels Nov 5, 2024
@llvmbot
Copy link

llvmbot commented Nov 5, 2024

@llvm/pr-subscribers-hlsl

@llvm/pr-subscribers-clang

Author: Joshua Batista (bob80905)

Changes

This PR adds empty struct cases to the test file for the builtin.


Full diff: https://github.com/llvm/llvm-project/pull/115045.diff

1 Files Affected:

  • (modified) clang/test/SemaHLSL/Types/Traits/IsTypedResourceElementCompatible.hlsl (+2)
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), "");
+
+

@llvmbot llvmbot added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Nov 5, 2024
Copy link
Collaborator

@llvm-beanz llvm-beanz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is actually a bigger problem with your earlier PR that we need to address.

There is an inconsistency in the design document. Specifically in the beginning of the document it says:

Element types for typed buffer resources:

  • Are not intangible (e.g., isn't a resource type)
  • Must be vectors or scalars of arithmetic types, not bools nor enums nor arrays
  • Should be a scalar or homogenous vector of a floating-point or integer type, with a maximum of 4 components after translating 64-bit components into pairs of uint32_t components

(edit: fixed formatting on quoted text, the formatting error is in the original document)

By this, elements should either be scalar or vectors, but not struct types.

The document later goes on to list test cases that are struct types.

I believe we had determined that DXC generates invalid code for some (most? all?) cases of structs in typed buffer elements, so we had determined to not support structs as element types in Clang.

@bob80905
Copy link
Contributor Author

bob80905 commented Nov 6, 2024

I believe we had determined that DXC generates invalid code for some (most? all?) cases of structs in typed buffer elements, so we had determined to not support structs as element types in Clang.

Correct, I'll edit the spec to reflect this more clearly. I've removed most of the struct tests.

@llvm-beanz
Copy link
Collaborator

Correct, I'll edit the spec to reflect this more clearly. I've removed most of the struct tests.
I don't think that solves this problem. The code as implemented doesn't match what it should be doing. You shouldn't need to build the flattened type list if only vectors and scalars are allowed so we should be able to simplify this implementation.

Copy link
Contributor

@coopp coopp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

Comment on lines 2209 to 2211
if (CanonicalType->getAs<clang::RecordType>()) {
return false;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: https://llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements

Suggested change
if (CanonicalType->getAs<clang::RecordType>()) {
return false;
}
if (CanonicalType->getAs<clang::RecordType>())
return false;

llvm::SmallVector<QualType, 4> QTTypes;
BuildFlattenedTypeList(QT, QTTypes);
// the only other valid builtin types are scalars or vectors
if (const BuiltinType *BT = CanonicalType->getAs<BuiltinType>()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vectors aren't BuitinType, so this can probably be simplified. Something like:

  // All arithmetic and enumeration types are valid.
  if (QT->isArithmeticType() || QT->isEnumeralType())
    return true;

Comment on lines 2231 to 2234
QualType ElTy = VT->getElementType();
int TotalSizeInBytes = (SemaRef.Context.getTypeSize(ElTy) / 8) * ArraySize;

if (TotalSizeInBytes > 16)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be simplified to:

Suggested change
QualType ElTy = VT->getElementType();
int TotalSizeInBytes = (SemaRef.Context.getTypeSize(ElTy) / 8) * ArraySize;
if (TotalSizeInBytes > 16)
if (SemaRef.Context.getTypeSize(QT) > 16)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With a division by 8, yes that is a good simplification

// check if the outer type was an array type
if (QT->isArrayType())
// UDT types are not allowed
clang::QualType CanonicalType = QT.getCanonicalType();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of the ways you're actually using this you likely don't need to query the canonical type. QT->isRecordType() will query the type of the canonical type directly.


_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(TypeDefTest), "");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to remove all these tests, or just update them to expect false results?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They could be left in and switched to false, but it doesn't seem valuable. All structs are disallowed, so I think just one struct test would suffice.

_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(SimpleTemplate<__hlsl_resource_t>), "");

_Static_assert(__builtin_hlsl_is_typed_resource_element_compatible(SimpleTemplate<float>), "");
// structs not allowed
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change may be a little too aggressive at removing test cases. All the struct cases should return false, but we could maybe test a few different struct formations. Some key ones to cover: forward declaration (incomplete), empty structure, template struct, template struct containing a vector that would be valid.


typedef int myInt;
typedef vector<int, 8> int8;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also have typedef tests that fail, the only one you have right now is a successful case.

What about arrays?

_Static_assert(!__builtin_hlsl_is_typed_resource_element_compatible(float[3]), "");

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The typedef test that I have right now does return false when evaluated by the builtin, it's a typedef of 8 ints in a vector. I also test for arrays with half[4]. Are these sufficient?

@bob80905 bob80905 merged commit 47889cd into llvm:main Nov 15, 2024
8 checks passed
@bogner
Copy link
Contributor

bogner commented Nov 15, 2024

When you change what a PR does, please remember to update the title and description. This went in saying it's about adding some test cases but it actually changes much more than that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category HLSL HLSL Language Support
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

6 participants