[clang] [llvm] [HLSL] Print struct body definition when within the context of defining a target extension type (PR #115971)

Joshua Batista via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 21 17:09:13 PST 2024


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

>From 7413ceb21a6e0ac9212ef6317763ee0eff559612 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Tue, 12 Nov 2024 16:44:00 -0800
Subject: [PATCH 1/4] print struct body within target ext ty context

---
 .../test/AST/HLSL/StructuredBuffer-AST-2.hlsl | 30 +++++++++++++++++++
 llvm/lib/IR/AsmWriter.cpp                     | 10 +++++--
 2 files changed, 38 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl

diff --git a/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl b/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl
new file mode 100644
index 00000000000000..73073b3f6f2839
--- /dev/null
+++ b/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl
@@ -0,0 +1,30 @@
+// RUN: %clang_dxc -T cs_6_6 %s | FileCheck %s
+
+// The purpose of this test is to ensure that the AST writer
+// only emits struct bodies when within the context of a 
+// larger object that is being outputted on the RHS.
+
+
+// note that "{ <4 x float> }" in the check below is a struct type, but only the
+// body is emitted on the RHS because we are already in the context of a
+// target extension type definition (class.hlsl::StructuredBuffer)
+// CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", { <4 x float> }, 0, 0), %struct.mystruct }
+// CHECK: %struct.mystruct = type { <4 x float> }
+// CHECK: %dx.types.Handle = type { ptr }
+// CHECK: %dx.types.ResBind = type { i32, i32, i32, i8 }
+// CHECK: %dx.types.ResourceProperties = type { i32, i32 }
+
+struct mystruct
+{
+    float4 Color;
+};
+
+StructuredBuffer<mystruct> my_buffer : register(t2, space4);
+
+export float4 test()
+{
+    return my_buffer[0].Color;
+}
+
+[numthreads(1,1,1)]
+void main() {}
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 3c1cb76622bbb7..d2705ff4b30fb8 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -649,8 +649,14 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) {
     OS << "target(\"";
     printEscapedString(Ty->getTargetExtName(), OS);
     OS << "\"";
-    for (Type *Inner : TETy->type_params())
-      OS << ", " << *Inner;
+    for (Type *Inner : TETy->type_params()) {
+      OS << ", ";
+      if (Inner->isStructTy()) {
+        StructType *STy = cast<StructType>(Inner);
+        printStructBody(STy, OS);
+      } else
+        OS << *Inner;
+    }
     for (unsigned IntParam : TETy->int_params())
       OS << ", " << IntParam;
     OS << ")";

>From 69d90f218b9702f4bd194507e54b5af86e38d3b3 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Wed, 13 Nov 2024 11:55:28 -0800
Subject: [PATCH 2/4] fix runline

---
 clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl b/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl
index 73073b3f6f2839..6b71ddd567249f 100644
--- a/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl
+++ b/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl
@@ -1,4 +1,4 @@
-// RUN: %clang_dxc -T cs_6_6 %s | FileCheck %s
+// RUN: %clang_cc1 -triple dxil-unknown-shadermodel6.6-compute -S -finclude-default-header -o - %s | FileCheck %s
 
 // The purpose of this test is to ensure that the AST writer
 // only emits struct bodies when within the context of a 

>From 3a1bdbacf556e2abffc2172721d66291e5f1e3ce Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Wed, 13 Nov 2024 13:54:54 -0800
Subject: [PATCH 3/4] undo change

---
 llvm/lib/IR/AsmWriter.cpp | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index d2705ff4b30fb8..e1c8fa834984d9 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -649,14 +649,8 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) {
     OS << "target(\"";
     printEscapedString(Ty->getTargetExtName(), OS);
     OS << "\"";
-    for (Type *Inner : TETy->type_params()) {
-      OS << ", ";
-      if (Inner->isStructTy()) {
-        StructType *STy = cast<StructType>(Inner);
-        printStructBody(STy, OS);
-      } else
-        OS << *Inner;
-    }
+    for (Type *Inner : TETy->type_params()) 
+      OS << ", " << *Inner;
     for (unsigned IntParam : TETy->int_params())
       OS << ", " << IntParam;
     OS << ")";

>From c3e6120c0d3efb7b5aeae864e164976a1d869b6f Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Thu, 21 Nov 2024 17:08:57 -0800
Subject: [PATCH 4/4] convert named to anonymous structs when creating target
 ext types

---
 clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl |  9 +++++----
 llvm/lib/IR/Type.cpp                            | 13 +++++++++++--
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl b/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl
index 6b71ddd567249f..1edec7835f16c7 100644
--- a/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl
+++ b/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl
@@ -1,13 +1,14 @@
 // RUN: %clang_cc1 -triple dxil-unknown-shadermodel6.6-compute -S -finclude-default-header -o - %s | FileCheck %s
 
-// The purpose of this test is to ensure that the AST writer
-// only emits struct bodies when within the context of a 
-// larger object that is being outputted on the RHS.
-
+// The purpose of this test is to ensure that the target
+// extension type associated with the structured buffer only
+// contains anonymous struct types, rather than named
+// struct types
 
 // note that "{ <4 x float> }" in the check below is a struct type, but only the
 // body is emitted on the RHS because we are already in the context of a
 // target extension type definition (class.hlsl::StructuredBuffer)
+
 // CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", { <4 x float> }, 0, 0), %struct.mystruct }
 // CHECK: %struct.mystruct = type { <4 x float> }
 // CHECK: %dx.types.Handle = type { ptr }
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index 88ede0d35fa3ee..bc285fe31c44ca 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -794,8 +794,17 @@ TargetExtType::TargetExtType(LLVMContext &C, StringRef Name,
   // Parameter storage immediately follows the class in allocation.
   Type **Params = reinterpret_cast<Type **>(this + 1);
   ContainedTys = Params;
-  for (Type *T : Types)
-    *Params++ = T;
+  for (Type *T : Types) {
+    // target ext type parameters may not be named struct types
+    // so we should convert any named struct types to anonymous
+    // struct types in the parameter list
+    Type *ConvertedTy = T;
+    if (auto *STy = dyn_cast<StructType>(T)) {
+      if (STy->hasName())
+        ConvertedTy = StructType::get(C, STy->elements(), /*isPacked=*/false);
+    }
+    *Params++ = ConvertedTy;
+  }
 
   setSubclassData(Ints.size());
   unsigned *IntParamSpace = reinterpret_cast<unsigned *>(Params);



More information about the cfe-commits mailing list