Skip to content

Conversation

@hekota
Copy link
Member

@hekota hekota commented Mar 7, 2025

Fixes #130191

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen IR generation bugs: mangling, exceptions, etc. backend:DirectX HLSL HLSL Language Support labels Mar 7, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 7, 2025

@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-hlsl

Author: Helena Kotas (hekota)

Changes

Fixes #130191


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

2 Files Affected:

  • (modified) clang/lib/CodeGen/Targets/DirectX.cpp (+8-2)
  • (modified) clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl (+4-3)
diff --git a/clang/lib/CodeGen/Targets/DirectX.cpp b/clang/lib/CodeGen/Targets/DirectX.cpp
index 77091eb45f5cf..0556527e2fdd6 100644
--- a/clang/lib/CodeGen/Targets/DirectX.cpp
+++ b/clang/lib/CodeGen/Targets/DirectX.cpp
@@ -59,8 +59,14 @@ llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(
     SmallVector<unsigned, 3> Ints = {/*IsWriteable*/ ResAttrs.ResourceClass ==
                                          llvm::dxil::ResourceClass::UAV,
                                      /*IsROV*/ ResAttrs.IsROV};
-    if (!ResAttrs.RawBuffer)
-      Ints.push_back(/*IsSigned*/ ContainedTy->isSignedIntegerType());
+    if (!ResAttrs.RawBuffer) {
+      const clang::Type *ElemType = ContainedTy->getUnqualifiedDesugaredType();
+      if (ElemType->isVectorType())
+        ElemType = cast<clang::VectorType>(ElemType)
+                       ->getElementType()
+                       ->getUnqualifiedDesugaredType();
+      Ints.push_back(/*IsSigned*/ ElemType->isSignedIntegerType());
+    }
 
     return llvm::TargetExtType::get(Ctx, TypeName, {ElemType}, Ints);
   }
diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl
index 11c77644a906d..0944ad59d5fb5 100644
--- a/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl
@@ -10,10 +10,11 @@
 // DXIL: %"class.hlsl::RWBuffer.5" = type { target("dx.TypedBuffer", half, 1, 0, 0) }
 // DXIL: %"class.hlsl::RWBuffer.6" = type { target("dx.TypedBuffer", float, 1, 0, 0) }
 // DXIL: %"class.hlsl::RWBuffer.7" = type { target("dx.TypedBuffer", double, 1, 0, 0) }
-// DXIL: %"class.hlsl::RWBuffer.8" = type { target("dx.TypedBuffer", <4 x i16>, 1, 0, 0) }
+// DXIL: %"class.hlsl::RWBuffer.8" = type { target("dx.TypedBuffer", <4 x i16>, 1, 0, 1) }
 // DXIL: %"class.hlsl::RWBuffer.9" = type { target("dx.TypedBuffer", <3 x i32>, 1, 0, 0) }
 // DXIL: %"class.hlsl::RWBuffer.10" = type { target("dx.TypedBuffer", <2 x half>, 1, 0, 0) }
 // DXIL: %"class.hlsl::RWBuffer.11" = type { target("dx.TypedBuffer", <3 x float>, 1, 0, 0) }
+// DXIL: %"class.hlsl::RWBuffer.12" = type { target("dx.TypedBuffer", <4 x i32>, 1, 0, 1) }
 
 // SPIRV: %"class.hlsl::RWBuffer" = type { target("spirv.Image", i16, 5, 2, 0, 0, 2, 0) }
 // SPIRV: %"class.hlsl::RWBuffer.0" = type { target("spirv.Image", i16, 5, 2, 0, 0, 2, 0) }
@@ -28,8 +29,7 @@
 // SPIRV: %"class.hlsl::RWBuffer.9" = type { target("spirv.Image", i32, 5, 2, 0, 0, 2, 0) }
 // SPIRV: %"class.hlsl::RWBuffer.10" = type { target("spirv.Image", half, 5, 2, 0, 0, 2, 0) }
 // SPIRV: %"class.hlsl::RWBuffer.11" = type { target("spirv.Image", float, 5, 2, 0, 0, 2, 0) }
-
-
+// SPIRV: %"class.hlsl::RWBuffer.12" = type { target("spirv.Image", i32, 5, 2, 0, 0, 2, 0) }
 
 RWBuffer<int16_t> BufI16;
 RWBuffer<uint16_t> BufU16;
@@ -44,6 +44,7 @@ RWBuffer< vector<int16_t, 4> > BufI16x4;
 RWBuffer< vector<uint, 3> > BufU32x3;
 RWBuffer<half2> BufF16x2;
 RWBuffer<float3> BufF32x3;
+RWBuffer<int4> BufI32x4;
 // TODO: RWBuffer<snorm half> BufSNormF16; -> 11
 // TODO: RWBuffer<unorm half> BufUNormF16; -> 12
 // TODO: RWBuffer<snorm float> BufSNormF32; -> 13

@llvmbot
Copy link
Member

llvmbot commented Mar 7, 2025

@llvm/pr-subscribers-clang

Author: Helena Kotas (hekota)

Changes

Fixes #130191


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

2 Files Affected:

  • (modified) clang/lib/CodeGen/Targets/DirectX.cpp (+8-2)
  • (modified) clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl (+4-3)
diff --git a/clang/lib/CodeGen/Targets/DirectX.cpp b/clang/lib/CodeGen/Targets/DirectX.cpp
index 77091eb45f5cf..0556527e2fdd6 100644
--- a/clang/lib/CodeGen/Targets/DirectX.cpp
+++ b/clang/lib/CodeGen/Targets/DirectX.cpp
@@ -59,8 +59,14 @@ llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(
     SmallVector<unsigned, 3> Ints = {/*IsWriteable*/ ResAttrs.ResourceClass ==
                                          llvm::dxil::ResourceClass::UAV,
                                      /*IsROV*/ ResAttrs.IsROV};
-    if (!ResAttrs.RawBuffer)
-      Ints.push_back(/*IsSigned*/ ContainedTy->isSignedIntegerType());
+    if (!ResAttrs.RawBuffer) {
+      const clang::Type *ElemType = ContainedTy->getUnqualifiedDesugaredType();
+      if (ElemType->isVectorType())
+        ElemType = cast<clang::VectorType>(ElemType)
+                       ->getElementType()
+                       ->getUnqualifiedDesugaredType();
+      Ints.push_back(/*IsSigned*/ ElemType->isSignedIntegerType());
+    }
 
     return llvm::TargetExtType::get(Ctx, TypeName, {ElemType}, Ints);
   }
diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl
index 11c77644a906d..0944ad59d5fb5 100644
--- a/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl
@@ -10,10 +10,11 @@
 // DXIL: %"class.hlsl::RWBuffer.5" = type { target("dx.TypedBuffer", half, 1, 0, 0) }
 // DXIL: %"class.hlsl::RWBuffer.6" = type { target("dx.TypedBuffer", float, 1, 0, 0) }
 // DXIL: %"class.hlsl::RWBuffer.7" = type { target("dx.TypedBuffer", double, 1, 0, 0) }
-// DXIL: %"class.hlsl::RWBuffer.8" = type { target("dx.TypedBuffer", <4 x i16>, 1, 0, 0) }
+// DXIL: %"class.hlsl::RWBuffer.8" = type { target("dx.TypedBuffer", <4 x i16>, 1, 0, 1) }
 // DXIL: %"class.hlsl::RWBuffer.9" = type { target("dx.TypedBuffer", <3 x i32>, 1, 0, 0) }
 // DXIL: %"class.hlsl::RWBuffer.10" = type { target("dx.TypedBuffer", <2 x half>, 1, 0, 0) }
 // DXIL: %"class.hlsl::RWBuffer.11" = type { target("dx.TypedBuffer", <3 x float>, 1, 0, 0) }
+// DXIL: %"class.hlsl::RWBuffer.12" = type { target("dx.TypedBuffer", <4 x i32>, 1, 0, 1) }
 
 // SPIRV: %"class.hlsl::RWBuffer" = type { target("spirv.Image", i16, 5, 2, 0, 0, 2, 0) }
 // SPIRV: %"class.hlsl::RWBuffer.0" = type { target("spirv.Image", i16, 5, 2, 0, 0, 2, 0) }
@@ -28,8 +29,7 @@
 // SPIRV: %"class.hlsl::RWBuffer.9" = type { target("spirv.Image", i32, 5, 2, 0, 0, 2, 0) }
 // SPIRV: %"class.hlsl::RWBuffer.10" = type { target("spirv.Image", half, 5, 2, 0, 0, 2, 0) }
 // SPIRV: %"class.hlsl::RWBuffer.11" = type { target("spirv.Image", float, 5, 2, 0, 0, 2, 0) }
-
-
+// SPIRV: %"class.hlsl::RWBuffer.12" = type { target("spirv.Image", i32, 5, 2, 0, 0, 2, 0) }
 
 RWBuffer<int16_t> BufI16;
 RWBuffer<uint16_t> BufU16;
@@ -44,6 +44,7 @@ RWBuffer< vector<int16_t, 4> > BufI16x4;
 RWBuffer< vector<uint, 3> > BufU32x3;
 RWBuffer<half2> BufF16x2;
 RWBuffer<float3> BufF32x3;
+RWBuffer<int4> BufI32x4;
 // TODO: RWBuffer<snorm half> BufSNormF16; -> 11
 // TODO: RWBuffer<unorm half> BufUNormF16; -> 12
 // TODO: RWBuffer<snorm float> BufSNormF32; -> 13

@llvmbot
Copy link
Member

llvmbot commented Mar 7, 2025

@llvm/pr-subscribers-backend-directx

Author: Helena Kotas (hekota)

Changes

Fixes #130191


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

2 Files Affected:

  • (modified) clang/lib/CodeGen/Targets/DirectX.cpp (+8-2)
  • (modified) clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl (+4-3)
diff --git a/clang/lib/CodeGen/Targets/DirectX.cpp b/clang/lib/CodeGen/Targets/DirectX.cpp
index 77091eb45f5cf..0556527e2fdd6 100644
--- a/clang/lib/CodeGen/Targets/DirectX.cpp
+++ b/clang/lib/CodeGen/Targets/DirectX.cpp
@@ -59,8 +59,14 @@ llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(
     SmallVector<unsigned, 3> Ints = {/*IsWriteable*/ ResAttrs.ResourceClass ==
                                          llvm::dxil::ResourceClass::UAV,
                                      /*IsROV*/ ResAttrs.IsROV};
-    if (!ResAttrs.RawBuffer)
-      Ints.push_back(/*IsSigned*/ ContainedTy->isSignedIntegerType());
+    if (!ResAttrs.RawBuffer) {
+      const clang::Type *ElemType = ContainedTy->getUnqualifiedDesugaredType();
+      if (ElemType->isVectorType())
+        ElemType = cast<clang::VectorType>(ElemType)
+                       ->getElementType()
+                       ->getUnqualifiedDesugaredType();
+      Ints.push_back(/*IsSigned*/ ElemType->isSignedIntegerType());
+    }
 
     return llvm::TargetExtType::get(Ctx, TypeName, {ElemType}, Ints);
   }
diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl
index 11c77644a906d..0944ad59d5fb5 100644
--- a/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl
@@ -10,10 +10,11 @@
 // DXIL: %"class.hlsl::RWBuffer.5" = type { target("dx.TypedBuffer", half, 1, 0, 0) }
 // DXIL: %"class.hlsl::RWBuffer.6" = type { target("dx.TypedBuffer", float, 1, 0, 0) }
 // DXIL: %"class.hlsl::RWBuffer.7" = type { target("dx.TypedBuffer", double, 1, 0, 0) }
-// DXIL: %"class.hlsl::RWBuffer.8" = type { target("dx.TypedBuffer", <4 x i16>, 1, 0, 0) }
+// DXIL: %"class.hlsl::RWBuffer.8" = type { target("dx.TypedBuffer", <4 x i16>, 1, 0, 1) }
 // DXIL: %"class.hlsl::RWBuffer.9" = type { target("dx.TypedBuffer", <3 x i32>, 1, 0, 0) }
 // DXIL: %"class.hlsl::RWBuffer.10" = type { target("dx.TypedBuffer", <2 x half>, 1, 0, 0) }
 // DXIL: %"class.hlsl::RWBuffer.11" = type { target("dx.TypedBuffer", <3 x float>, 1, 0, 0) }
+// DXIL: %"class.hlsl::RWBuffer.12" = type { target("dx.TypedBuffer", <4 x i32>, 1, 0, 1) }
 
 // SPIRV: %"class.hlsl::RWBuffer" = type { target("spirv.Image", i16, 5, 2, 0, 0, 2, 0) }
 // SPIRV: %"class.hlsl::RWBuffer.0" = type { target("spirv.Image", i16, 5, 2, 0, 0, 2, 0) }
@@ -28,8 +29,7 @@
 // SPIRV: %"class.hlsl::RWBuffer.9" = type { target("spirv.Image", i32, 5, 2, 0, 0, 2, 0) }
 // SPIRV: %"class.hlsl::RWBuffer.10" = type { target("spirv.Image", half, 5, 2, 0, 0, 2, 0) }
 // SPIRV: %"class.hlsl::RWBuffer.11" = type { target("spirv.Image", float, 5, 2, 0, 0, 2, 0) }
-
-
+// SPIRV: %"class.hlsl::RWBuffer.12" = type { target("spirv.Image", i32, 5, 2, 0, 0, 2, 0) }
 
 RWBuffer<int16_t> BufI16;
 RWBuffer<uint16_t> BufU16;
@@ -44,6 +44,7 @@ RWBuffer< vector<int16_t, 4> > BufI16x4;
 RWBuffer< vector<uint, 3> > BufU32x3;
 RWBuffer<half2> BufF16x2;
 RWBuffer<float3> BufF32x3;
+RWBuffer<int4> BufI32x4;
 // TODO: RWBuffer<snorm half> BufSNormF16; -> 11
 // TODO: RWBuffer<unorm half> BufUNormF16; -> 12
 // TODO: RWBuffer<snorm float> BufSNormF32; -> 13

@hekota hekota changed the title [HLSL] Make sure isSigned flag is set on target type for TypedBuffer resources for signed int vectors [HLSL] Make sure isSigned flag is set on target type for TypedBuffer resources with signed int vectors Mar 7, 2025
Ints.push_back(/*IsSigned*/ ContainedTy->isSignedIntegerType());
if (!ResAttrs.RawBuffer) {
const clang::Type *ElemType = ContainedTy->getUnqualifiedDesugaredType();
if (ElemType->isVectorType())
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it make sense to add a while loop here?
Could it be more than a 2D vector?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, vectors cannot be nested, only arrays.

Copy link
Contributor

@bob80905 bob80905 left a comment

Choose a reason for hiding this comment

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

LGTM for DXIL. Is there a plan to do this with SPIR-V too?

@hekota hekota merged commit cb64a36 into llvm:main Mar 14, 2025
16 checks passed
@hekota
Copy link
Member Author

hekota commented Mar 14, 2025

LGTM for DXIL. Is there a plan to do this with SPIR-V too?

SPIR-V is generating different target type and it does not seem to have the 'signed' flag:
See

return getSPIRVImageTypeFromHLSLResource(ResAttrs, ElemType, Ctx);

@damyanp damyanp moved this to Closed in HLSL Support Apr 25, 2025
@damyanp damyanp removed this from HLSL Support Jun 25, 2025
@hekota hekota deleted the signed-int-vector-fix branch August 19, 2025 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:DirectX clang:codegen IR generation bugs: mangling, exceptions, etc. clang Clang issues not falling into any other category HLSL HLSL Language Support

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[HLSL] Typed buffer with signed int vector is translated as unsigned

4 participants