https://github.com/hekota updated 
https://github.com/llvm/llvm-project/pull/128991

>From e982a61657da5eb4c7f2618c95f0c6d3493cb854 Mon Sep 17 00:00:00 2001
From: Helena Kotas <heko...@microsoft.com>
Date: Wed, 26 Feb 2025 19:14:20 -0800
Subject: [PATCH 1/3] [HLSL] Implement explicit layout for default constant
 buffer

Fixes #123801
---
 clang/lib/CodeGen/CGHLSLRuntime.cpp           | 38 ++++++--
 clang/lib/CodeGen/CGHLSLRuntime.h             |  2 +-
 clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp | 87 +++++++++++++++----
 clang/lib/CodeGen/HLSLBufferLayoutBuilder.h   |  7 +-
 clang/lib/CodeGen/TargetInfo.h                |  2 +-
 clang/lib/CodeGen/Targets/DirectX.cpp         |  4 +-
 clang/lib/CodeGen/Targets/SPIR.cpp            |  4 +-
 clang/lib/Sema/SemaHLSL.cpp                   | 12 +++
 .../CodeGenHLSL/cbuffer_with_packoffset.hlsl  | 17 +++-
 .../default_cbuffer_with_layout.hlsl          | 37 ++++++++
 10 files changed, 175 insertions(+), 35 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/default_cbuffer_with_layout.hlsl

diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp 
b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index ed6d2036cb984..6f476d7df4578 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -70,7 +70,7 @@ void addDxilValVersion(StringRef ValVersionStr, llvm::Module 
&M) {
 
 llvm::Type *
 CGHLSLRuntime::convertHLSLSpecificType(const Type *T,
-                                       SmallVector<unsigned> *Packoffsets) {
+                                       SmallVector<int32_t> *Packoffsets) {
   assert(T->isHLSLSpecificType() && "Not an HLSL specific type!");
 
   // Check if the target has a specific translation for this type first.
@@ -179,21 +179,45 @@ createBufferHandleType(const HLSLBufferDecl *BufDecl) {
   return cast<HLSLAttributedResourceType>(QT.getTypePtr());
 }
 
+// Iterates over all declarations in the HLSL buffer and based on the
+// packoffset or register(c#) annotations it fills outs the Layout
+// vector with the user-specified layout offsets.
+// The buffer offsets can be specified 2 ways:
+// 1. declarations in cbuffer {} block can have a packoffset annotation
+//    (translates to HLSLPackOffsetAttr)
+// 2. default constant buffer declarations at global scope can have
+//    register(c#) annotations (translates to HLSLResourceBindingAttr with
+//    RegisterType::C)
+// It is not quaranteed that all declarations in a buffer have an annotation.
+// For those where it is not specified a -1 value is added to the Layout
+// vector. In the final layout these declarations will be placed at the end
+// of the HLSL buffer after all of the elements with specified offset.  
 static void fillPackoffsetLayout(const HLSLBufferDecl *BufDecl,
-                                 SmallVector<unsigned> &Layout) {
+                                 SmallVector<int32_t> &Layout) {
   assert(Layout.empty() && "expected empty vector for layout");
   assert(BufDecl->hasValidPackoffset());
 
-  for (Decl *D : BufDecl->decls()) {
+  for (Decl *D : BufDecl->buffer_decls()) {
     if (isa<CXXRecordDecl, EmptyDecl>(D) || isa<FunctionDecl>(D)) {
       continue;
     }
     VarDecl *VD = dyn_cast<VarDecl>(D);
     if (!VD || VD->getType().getAddressSpace() != LangAS::hlsl_constant)
       continue;
-    assert(VD->hasAttr<HLSLPackOffsetAttr>() &&
-           "expected packoffset attribute on every declaration");
-    size_t Offset = VD->getAttr<HLSLPackOffsetAttr>()->getOffsetInBytes();
+    size_t Offset = -1;
+    if (VD->hasAttrs()) {
+      for (auto *Attr : VD->getAttrs()) {
+        if (auto *POA = dyn_cast<HLSLPackOffsetAttr>(Attr)) {
+          Offset = POA->getOffsetInBytes();
+        } else if (auto *RBA = dyn_cast<HLSLResourceBindingAttr>(Attr)) {
+          if (RBA->getRegisterType() ==
+              HLSLResourceBindingAttr::RegisterType::C) {
+            // size of constant buffer row is 16 bytes
+            Offset = RBA->getSlotNumber() * 16U;
+          }
+        }
+      }
+    }
     Layout.push_back(Offset);
   }
 }
@@ -212,7 +236,7 @@ void CGHLSLRuntime::addBuffer(const HLSLBufferDecl 
*BufDecl) {
     return;
 
   // create global variable for the constant buffer
-  SmallVector<unsigned> Layout;
+  SmallVector<int32_t> Layout;
   if (BufDecl->hasValidPackoffset())
     fillPackoffsetLayout(BufDecl, Layout);
 
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h 
b/clang/lib/CodeGen/CGHLSLRuntime.h
index a9da42324a038..c4550056175c1 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -146,7 +146,7 @@ class CGHLSLRuntime {
 
   llvm::Type *
   convertHLSLSpecificType(const Type *T,
-                          SmallVector<unsigned> *Packoffsets = nullptr);
+                          SmallVector<int32_t> *Packoffsets = nullptr);
 
   void annotateHLSLResource(const VarDecl *D, llvm::GlobalVariable *GV);
   void generateGlobalCtorDtorCalls();
diff --git a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp 
b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp
index 97262b76c0164..bf9bca48a4dd6 100644
--- a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp
@@ -10,6 +10,7 @@
 #include "CGHLSLRuntime.h"
 #include "CodeGenModule.h"
 #include "clang/AST/Type.h"
+#include <climits>
 
 
//===----------------------------------------------------------------------===//
 // Implementation of constant buffer layout common between DirectX and
@@ -58,9 +59,15 @@ namespace CodeGen {
 // classes) and calls layoutField to converts each field to its corresponding
 // LLVM type and to calculate its HLSL constant buffer layout. Any embedded
 // structs (or arrays of structs) are converted to target layout types as well.
+//
+// When Packoffsets are specified the elements will be placed based on the
+// user-specified offsets. Not all elements must have a packoffset/register(c#)
+// annotation though. For those that don't, the Packoffsets array will constain
+// -1 value instead. These elements must be placed at the end of the layout
+// after all of the elements with specific offset.  
 llvm::TargetExtType *HLSLBufferLayoutBuilder::createLayoutType(
     const RecordType *StructType,
-    const llvm::SmallVector<unsigned> *Packoffsets) {
+    const llvm::SmallVector<int32_t> *Packoffsets) {
 
   // check if we already have the layout type for this struct
   if (llvm::TargetExtType *Ty =
@@ -72,6 +79,8 @@ llvm::TargetExtType 
*HLSLBufferLayoutBuilder::createLayoutType(
   unsigned Index = 0; // packoffset index
   unsigned EndOffset = 0;
 
+  SmallVector<std::pair<const FieldDecl *, unsigned>> DelayLayoutFields;
+
   // reserve first spot in the layout vector for buffer size
   Layout.push_back(0);
 
@@ -89,14 +98,57 @@ llvm::TargetExtType 
*HLSLBufferLayoutBuilder::createLayoutType(
     RecordTypes.pop_back();
 
     for (const auto *FD : RT->getDecl()->fields()) {
-      assert((!Packoffsets || Index < Packoffsets->size()) &&
-             "number of elements in layout struct does not "
-             "match number of packoffset annotations");
+      unsigned FieldOffset = UINT_MAX;
+      llvm::Type *FieldType = nullptr;
+
+      if (Packoffsets) {
+        // have packoffset/register(c#) annotations
+        assert(Index < Packoffsets->size() &&
+               "number of elements in layout struct does not match number of "
+               "packoffset annotations");
+        int PO = (*Packoffsets)[Index++];
+        if (PO != -1) {
+          if (!layoutField(FD, EndOffset, FieldOffset, FieldType, PO))
+            return nullptr;
+        } else {
+          // No packoffset/register(cX) annotation on this field;
+          // Delay the layout until after all of the other elements
+          // annotated with packoffsets/register(cX) are processed.
+          DelayLayoutFields.emplace_back(FD, LayoutElements.size());
+          // reserve space for this field in the layout vector and elements 
list
+          Layout.push_back(UINT_MAX);
+          LayoutElements.push_back(nullptr);
+          continue;
+        }
+      } else {
+        if (!layoutField(FD, EndOffset, FieldOffset, FieldType))
+          return nullptr;
+      }
+
+      assert(FieldOffset != UINT_MAX && FieldType != nullptr);
+      Layout.push_back((unsigned)FieldOffset);
+      LayoutElements.push_back(FieldType);
+    }
+  }
 
-      if (!layoutField(FD, EndOffset, Layout, LayoutElements,
-                       Packoffsets ? (*Packoffsets)[Index] : -1))
+  // process delayed layouts
+  if (!DelayLayoutFields.empty()) {
+    for (auto I : DelayLayoutFields) {
+      const FieldDecl *FD = I.first;
+      unsigned IndexInLayoutElements = I.second;
+      // the first item in layout vector is size, so we need to offset the 
index
+      // by 1
+      unsigned IndexInLayout = IndexInLayoutElements + 1;
+      assert(Layout[IndexInLayout] == UINT_MAX &&
+             LayoutElements[IndexInLayoutElements] == nullptr);
+
+      unsigned FieldOffset = UINT_MAX;
+      llvm::Type *FieldType = nullptr;
+      if (!layoutField(FD, EndOffset, FieldOffset, FieldType))
         return nullptr;
-      Index++;
+
+      Layout[IndexInLayout] = (unsigned)FieldOffset;
+      LayoutElements[IndexInLayoutElements] = FieldType;
     }
   }
 
@@ -122,16 +174,19 @@ llvm::TargetExtType 
*HLSLBufferLayoutBuilder::createLayoutType(
 // The function converts a single field of HLSL Buffer to its corresponding
 // LLVM type and calculates it's layout. Any embedded structs (or
 // arrays of structs) are converted to target layout types as well.
-// The converted type is appended to the LayoutElements list, the element
-// offset is added to the Layout list and the EndOffset updated to the offset
-// just after the lay-ed out element (which is basically the size of the
-// buffer).
+// The converted type is set to the FieldType parameter, the element
+// offset is set to the FieldOffset parameter. The EndOffset (=size of the
+// buffer) is also updated accordingly to the offset just after the placed
+// element, unless the incoming EndOffset already larger (may happen in case
+// of unsorted packoffset annotations).
 // Returns true if the conversion was successful.
 // The packoffset parameter contains the field's layout offset provided by the
 // user or -1 if there was no packoffset (or register(cX)) annotation.
-bool HLSLBufferLayoutBuilder::layoutField(
-    const FieldDecl *FD, unsigned &EndOffset, SmallVector<unsigned> &Layout,
-    SmallVector<llvm::Type *> &LayoutElements, int Packoffset) {
+bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD,
+                                          unsigned &EndOffset,
+                                          unsigned &FieldOffset,
+                                          llvm::Type *&FieldType,
+                                          int Packoffset) {
 
   // Size of element; for arrays this is a size of a single element in the
   // array. Total array size of calculated as (ArrayCount-1) * ArrayStride +
@@ -220,8 +275,8 @@ bool HLSLBufferLayoutBuilder::layoutField(
   EndOffset = std::max<unsigned>(EndOffset, NewEndOffset);
 
   // add the layout element and offset to the lists
-  Layout.push_back(ElemOffset);
-  LayoutElements.push_back(ElemLayoutTy);
+  FieldOffset = ElemOffset;
+  FieldType = ElemLayoutTy;
   return true;
 }
 
diff --git a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.h 
b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.h
index 57bb17c557b9c..b4550757a93b4 100644
--- a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.h
+++ b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.h
@@ -35,13 +35,12 @@ class HLSLBufferLayoutBuilder {
   // the Layout is the size followed by offsets for each struct element.
   llvm::TargetExtType *
   createLayoutType(const RecordType *StructType,
-                   const llvm::SmallVector<unsigned> *Packoffsets = nullptr);
+                   const llvm::SmallVector<int32_t> *Packoffsets = nullptr);
 
 private:
   bool layoutField(const clang::FieldDecl *FD, unsigned &EndOffset,
-                   llvm::SmallVector<unsigned> &Layout,
-                   llvm::SmallVector<llvm::Type *> &LayoutElements,
-                   int Packoffset);
+                   unsigned &FieldOffset, llvm::Type *&FieldType,
+                   int Packoffset = -1);
 };
 
 } // namespace CodeGen
diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h
index 86057c14a549e..5df19fbef1e5b 100644
--- a/clang/lib/CodeGen/TargetInfo.h
+++ b/clang/lib/CodeGen/TargetInfo.h
@@ -441,7 +441,7 @@ class TargetCodeGenInfo {
   /// Return an LLVM type that corresponds to a HLSL type
   virtual llvm::Type *
   getHLSLType(CodeGenModule &CGM, const Type *T,
-              const SmallVector<unsigned> *Packoffsets = nullptr) const {
+              const SmallVector<int32_t> *Packoffsets = nullptr) const {
     return nullptr;
   }
 
diff --git a/clang/lib/CodeGen/Targets/DirectX.cpp 
b/clang/lib/CodeGen/Targets/DirectX.cpp
index 77091eb45f5cf..8b94d01048c5d 100644
--- a/clang/lib/CodeGen/Targets/DirectX.cpp
+++ b/clang/lib/CodeGen/Targets/DirectX.cpp
@@ -31,12 +31,12 @@ class DirectXTargetCodeGenInfo : public TargetCodeGenInfo {
 
   llvm::Type *getHLSLType(
       CodeGenModule &CGM, const Type *T,
-      const SmallVector<unsigned> *Packoffsets = nullptr) const override;
+      const SmallVector<int32_t> *Packoffsets = nullptr) const override;
 };
 
 llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(
     CodeGenModule &CGM, const Type *Ty,
-    const SmallVector<unsigned> *Packoffsets) const {
+    const SmallVector<int32_t> *Packoffsets) const {
   auto *ResType = dyn_cast<HLSLAttributedResourceType>(Ty);
   if (!ResType)
     return nullptr;
diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp 
b/clang/lib/CodeGen/Targets/SPIR.cpp
index c94db31ae1a89..056228563aa25 100644
--- a/clang/lib/CodeGen/Targets/SPIR.cpp
+++ b/clang/lib/CodeGen/Targets/SPIR.cpp
@@ -54,7 +54,7 @@ class CommonSPIRTargetCodeGenInfo : public TargetCodeGenInfo {
   llvm::Type *getOpenCLType(CodeGenModule &CGM, const Type *T) const override;
   llvm::Type *getHLSLType(
       CodeGenModule &CGM, const Type *Ty,
-      const SmallVector<unsigned> *Packoffsets = nullptr) const override;
+      const SmallVector<int32_t> *Packoffsets = nullptr) const override;
   llvm::Type *getSPIRVImageTypeFromHLSLResource(
       const HLSLAttributedResourceType::Attributes &attributes,
       llvm::Type *ElementType, llvm::LLVMContext &Ctx) const;
@@ -371,7 +371,7 @@ llvm::Type 
*CommonSPIRTargetCodeGenInfo::getOpenCLType(CodeGenModule &CGM,
 
 llvm::Type *CommonSPIRTargetCodeGenInfo::getHLSLType(
     CodeGenModule &CGM, const Type *Ty,
-    const SmallVector<unsigned> *Packoffsets) const {
+    const SmallVector<int32_t> *Packoffsets) const {
   auto *ResType = dyn_cast<HLSLAttributedResourceType>(Ty);
   if (!ResType)
     return nullptr;
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index ffc3ac1b65854..507278219e500 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -1961,6 +1961,18 @@ void 
SemaHLSL::ActOnEndOfTranslationUnit(TranslationUnitDecl *TU) {
     SemaRef.getCurLexicalContext()->addDecl(DefaultCBuffer);
     createHostLayoutStructForBuffer(SemaRef, DefaultCBuffer);
 
+    // Set HasValidPackoffset if any of the decls has a register(c#) 
annotation;
+    for (const Decl *VD : DefaultCBufferDecls) {
+      if (const HLSLResourceBindingAttr *RBA =
+              VD->getAttr<HLSLResourceBindingAttr>()) {
+        if (RBA->getRegisterType() ==
+            HLSLResourceBindingAttr::RegisterType::C) {
+          DefaultCBuffer->setHasValidPackoffset(true);
+          break;
+        }
+      }
+    }
+
     DeclGroupRef DG(DefaultCBuffer);
     SemaRef.Consumer.HandleTopLevelDecl(DG);
   }
diff --git a/clang/test/CodeGenHLSL/cbuffer_with_packoffset.hlsl 
b/clang/test/CodeGenHLSL/cbuffer_with_packoffset.hlsl
index 870593986a976..81697cdc0f045 100644
--- a/clang/test/CodeGenHLSL/cbuffer_with_packoffset.hlsl
+++ b/clang/test/CodeGenHLSL/cbuffer_with_packoffset.hlsl
@@ -3,6 +3,7 @@
 // RUN:   -emit-llvm -disable-llvm-passes -o - | FileCheck %s
 
 // CHECK: %__cblayout_CB = type <{ float, double, <2 x i32> }>
+// CHECK: %__cblayout_CB_1 = type <{ float, <2 x float> }>
 
 // CHECK: @CB.cb = external constant target("dx.CBuffer", target("dx.Layout", 
%__cblayout_CB, 176, 16, 168, 88))
 // CHECK: @a = external addrspace(2) global float, align 4
@@ -15,6 +16,17 @@ cbuffer CB : register(b1, space3) {
   int2 c : packoffset(c5.z);
 }
 
+// CHECK: @CB.cb.1 = external constant target("dx.CBuffer", 
target("dx.Layout", %__cblayout_CB_1, 92, 88, 80))
+// CHECK: @x = external addrspace(2) global float, align 4
+// CHECK: @y = external addrspace(2) global <2 x float>, align 8
+
+// Missing packoffset annotation will produce a warning.
+// Element x will be placed after the element y that has an explicit 
packoffset.
+cbuffer CB : register(b0) {
+  float x;
+  float2 y : packoffset(c5);
+}
+
 // CHECK: define internal void @_init_resource_CB.cb()
 // CHECK-NEXT: entry:
 // CHECK-NEXT: %CB.cb_h = call target("dx.CBuffer", target("dx.Layout", 
%__cblayout_CB, 176, 16, 168, 88))
@@ -34,5 +46,6 @@ void main() {
   foo();
 }
 
-// CHECK: !hlsl.cbs = !{![[CB:[0-9]+]]}
-// CHECK: ![[CB]] = !{ptr @CB.cb, ptr addrspace(2) @a, ptr addrspace(2) @b, 
ptr addrspace(2) @c}
+// CHECK: !hlsl.cbs = !{![[CB1:[0-9]+]], ![[CB2:[0-9]+]]}
+// CHECK: ![[CB1]] = !{ptr @CB.cb, ptr addrspace(2) @a, ptr addrspace(2) @b, 
ptr addrspace(2) @c}
+// CHECK: ![[CB2]] = !{ptr @CB.cb.1, ptr addrspace(2) @x, ptr addrspace(2) @y}
diff --git a/clang/test/CodeGenHLSL/default_cbuffer_with_layout.hlsl 
b/clang/test/CodeGenHLSL/default_cbuffer_with_layout.hlsl
new file mode 100644
index 0000000000000..c4fd83679f84b
--- /dev/null
+++ b/clang/test/CodeGenHLSL/default_cbuffer_with_layout.hlsl
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.3-compute \
+// RUN:            -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s
+
+// CHECK: %"__cblayout_$Globals" = type <{ i32, float, [4 x double], <4 x 
i32>, <4 x float>,
+// CHECK-SAME: target("dx.Layout", %S, 8, 0) }>
+// CHECK: %S = type <{ <2 x float> }>
+
+// CHECK-DAG: @b = external addrspace(2) global float, align 4
+// CHECK-DAG: @d = external addrspace(2) global <4 x i32>, align 16
+// CHECK-DAG: @"$Globals.cb" = external constant target("dx.CBuffer",
+// CHECK-DAG-SAME: target("dx.Layout", %"__cblayout_$Globals", 144, 120, 16, 
32, 64, 128, 112))
+// CHECK-DAG: @a = external addrspace(2) global i32, align 4
+// CHECK-DAG: @c = external addrspace(2) global [4 x double], align 8
+// CHECK-DAG: @e = external addrspace(2) global <4 x float>, align 16
+// CHECK-DAG: @s = external addrspace(2) global target("dx.Layout", %S, 8, 0), 
align 8
+
+struct S {
+  float2 v;
+}; 
+
+int a;
+float b : register(c1);
+double c[4] : register(c2);
+int4 d : register(c4);
+float4 e;
+S s : register(c7);
+
+RWBuffer<float> Buf;
+
+[numthreads(4,1,1)]
+void main() {
+  Buf[0] = a;
+}
+
+// CHECK: !hlsl.cbs = !{![[CB:.*]]}
+// CHECK: ![[CB]] = !{ptr @"$Globals.cb", ptr addrspace(2) @a, ptr 
addrspace(2) @b, ptr addrspace(2) @c,
+// CHECK-SAME: ptr addrspace(2) @d, ptr addrspace(2) @e, ptr addrspace(2) @s}
\ No newline at end of file

>From 458d5f0b0583fb4cbeb1c8b8f6f460e231b66474 Mon Sep 17 00:00:00 2001
From: Helena Kotas <heko...@microsoft.com>
Date: Wed, 26 Feb 2025 19:27:16 -0800
Subject: [PATCH 2/3] clang-format

---
 clang/lib/CodeGen/CGHLSLRuntime.cpp           | 2 +-
 clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp | 2 +-
 clang/lib/CodeGen/Targets/DirectX.cpp         | 6 +++---
 clang/lib/CodeGen/Targets/SPIR.cpp            | 6 +++---
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp 
b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 6f476d7df4578..67256aa2be339 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -191,7 +191,7 @@ createBufferHandleType(const HLSLBufferDecl *BufDecl) {
 // It is not quaranteed that all declarations in a buffer have an annotation.
 // For those where it is not specified a -1 value is added to the Layout
 // vector. In the final layout these declarations will be placed at the end
-// of the HLSL buffer after all of the elements with specified offset.  
+// of the HLSL buffer after all of the elements with specified offset.
 static void fillPackoffsetLayout(const HLSLBufferDecl *BufDecl,
                                  SmallVector<int32_t> &Layout) {
   assert(Layout.empty() && "expected empty vector for layout");
diff --git a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp 
b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp
index bf9bca48a4dd6..7a92233ac9055 100644
--- a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp
@@ -64,7 +64,7 @@ namespace CodeGen {
 // user-specified offsets. Not all elements must have a packoffset/register(c#)
 // annotation though. For those that don't, the Packoffsets array will constain
 // -1 value instead. These elements must be placed at the end of the layout
-// after all of the elements with specific offset.  
+// after all of the elements with specific offset.
 llvm::TargetExtType *HLSLBufferLayoutBuilder::createLayoutType(
     const RecordType *StructType,
     const llvm::SmallVector<int32_t> *Packoffsets) {
diff --git a/clang/lib/CodeGen/Targets/DirectX.cpp 
b/clang/lib/CodeGen/Targets/DirectX.cpp
index 8b94d01048c5d..88a4b812db675 100644
--- a/clang/lib/CodeGen/Targets/DirectX.cpp
+++ b/clang/lib/CodeGen/Targets/DirectX.cpp
@@ -29,9 +29,9 @@ class DirectXTargetCodeGenInfo : public TargetCodeGenInfo {
   DirectXTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
       : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {}
 
-  llvm::Type *getHLSLType(
-      CodeGenModule &CGM, const Type *T,
-      const SmallVector<int32_t> *Packoffsets = nullptr) const override;
+  llvm::Type *
+  getHLSLType(CodeGenModule &CGM, const Type *T,
+              const SmallVector<int32_t> *Packoffsets = nullptr) const 
override;
 };
 
 llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(
diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp 
b/clang/lib/CodeGen/Targets/SPIR.cpp
index 056228563aa25..43f511e572d37 100644
--- a/clang/lib/CodeGen/Targets/SPIR.cpp
+++ b/clang/lib/CodeGen/Targets/SPIR.cpp
@@ -52,9 +52,9 @@ class CommonSPIRTargetCodeGenInfo : public TargetCodeGenInfo {
 
   unsigned getOpenCLKernelCallingConv() const override;
   llvm::Type *getOpenCLType(CodeGenModule &CGM, const Type *T) const override;
-  llvm::Type *getHLSLType(
-      CodeGenModule &CGM, const Type *Ty,
-      const SmallVector<int32_t> *Packoffsets = nullptr) const override;
+  llvm::Type *
+  getHLSLType(CodeGenModule &CGM, const Type *Ty,
+              const SmallVector<int32_t> *Packoffsets = nullptr) const 
override;
   llvm::Type *getSPIRVImageTypeFromHLSLResource(
       const HLSLAttributedResourceType::Attributes &attributes,
       llvm::Type *ElementType, llvm::LLVMContext &Ctx) const;

>From 22d9d1f241b966389f8947ca0de7b9f8cb63995b Mon Sep 17 00:00:00 2001
From: Helena Kotas <heko...@microsoft.com>
Date: Thu, 27 Feb 2025 11:33:46 -0800
Subject: [PATCH 3/3] code review feedback - fix typo and naked constant

---
 clang/lib/CodeGen/CGHLSLRuntime.cpp           | 4 ++--
 clang/lib/CodeGen/CGHLSLRuntime.h             | 2 ++
 clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp | 6 +++---
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp 
b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index 67256aa2be339..e8a54bff28e51 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -188,7 +188,7 @@ createBufferHandleType(const HLSLBufferDecl *BufDecl) {
 // 2. default constant buffer declarations at global scope can have
 //    register(c#) annotations (translates to HLSLResourceBindingAttr with
 //    RegisterType::C)
-// It is not quaranteed that all declarations in a buffer have an annotation.
+// It is not guaranteed that all declarations in a buffer have an annotation.
 // For those where it is not specified a -1 value is added to the Layout
 // vector. In the final layout these declarations will be placed at the end
 // of the HLSL buffer after all of the elements with specified offset.
@@ -213,7 +213,7 @@ static void fillPackoffsetLayout(const HLSLBufferDecl 
*BufDecl,
           if (RBA->getRegisterType() ==
               HLSLResourceBindingAttr::RegisterType::C) {
             // size of constant buffer row is 16 bytes
-            Offset = RBA->getSlotNumber() * 16U;
+            Offset = RBA->getSlotNumber() * 
CGHLSLRuntime::BufferRowSizeInBytes;
           }
         }
       }
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h 
b/clang/lib/CodeGen/CGHLSLRuntime.h
index c4550056175c1..eaccfa9852d34 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -134,6 +134,8 @@ class CGHLSLRuntime {
     BufferResBinding(HLSLResourceBindingAttr *Attr);
   };
 
+  static const unsigned BufferRowSizeInBytes = 16U;
+
 protected:
   CodeGenModule &CGM;
 
diff --git a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp 
b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp
index 7a92233ac9055..5163d69a8bd41 100644
--- a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp
@@ -196,8 +196,8 @@ bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl 
*FD,
   unsigned ArrayCount = 1;
   unsigned ArrayStride = 0;
 
-  const unsigned BufferRowAlign = 16U;
-  unsigned NextRowOffset = llvm::alignTo(EndOffset, BufferRowAlign);
+  unsigned NextRowOffset =
+      llvm::alignTo(EndOffset, CGHLSLRuntime::BufferRowSizeInBytes);
 
   llvm::Type *ElemLayoutTy = nullptr;
   QualType FieldTy = FD->getType();
@@ -227,7 +227,7 @@ bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl 
*FD,
           getScalarOrVectorSizeInBytes(CGM.getTypes().ConvertTypeForMem(Ty));
       ElemLayoutTy = CGM.getTypes().ConvertTypeForMem(FieldTy);
     }
-    ArrayStride = llvm::alignTo(ElemSize, BufferRowAlign);
+    ArrayStride = llvm::alignTo(ElemSize, CGHLSLRuntime::BufferRowSizeInBytes);
     ElemOffset = (Packoffset != -1) ? Packoffset : NextRowOffset;
 
   } else if (FieldTy->isStructureType()) {

_______________________________________________
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to