[clang] Clang][HLSL] Emit constant matrix values in column-major order (PR #227356)
Farzon Lotfi via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 29 08:52:32 PDT 2026
https://github.com/farzonl created https://github.com/llvm/llvm-project/pull/227356
Emit matrix APValues in the canonical column-major register layout, independent of the selected matrix memory layout.
When a constant is used as a row-major memory initializer, reorder its elements at the register-to-memory boundary. This preserves the physical layout of global and static row-major matrices while ensuring constexpr matrix expressions produce canonical register values.
Assisted by Cop-pilot GPT 5.6-Sol
>From 2177db6988a358127da874a03580ffc9a82e5fc5 Mon Sep 17 00:00:00 2001
From: Farzon Lotfi <farzonlotfi at microsoft.com>
Date: Tue, 29 Sep 2026 11:48:59 -0400
Subject: [PATCH] Clang][HLSL] Emit constant matrix values in column-major
order
Emit matrix APValues in the canonical column-major register layout,
independent of the selected matrix memory layout.
When a constant is used as a row-major memory initializer, reorder its
elements at the register-to-memory boundary. This preserves the physical
layout of global and static row-major matrices while ensuring constexpr
matrix expressions produce canonical register values.
Assisted by Cop-pilot GPT 5.6-Sol
---
clang/lib/CodeGen/CGExprConstant.cpp | 15 ++++++++++++---
.../BasicFeatures/MatrixInitializerListOrder.hlsl | 11 +++++++++++
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 3d8fefb4988b7..917be246b7346 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -2087,6 +2087,17 @@ llvm::Constant *ConstantEmitter::emitForMemory(CodeGenModule &CGM,
}
}
+ if (destType->isConstantMatrixType() &&
+ isMatrixRowMajor(CGM.getLangOpts(), destType)) {
+ const auto *MT = destType->castAs<ConstantMatrixType>();
+ SmallVector<llvm::Constant *, 16> Inits(MT->getNumElementsFlattened());
+ for (unsigned Row = 0; Row != MT->getNumRows(); ++Row)
+ for (unsigned Col = 0; Col != MT->getNumColumns(); ++Col)
+ Inits[MT->getRowMajorFlattenedIndex(Row, Col)] =
+ C->getAggregateElement(MT->getColumnMajorFlattenedIndex(Row, Col));
+ return llvm::ConstantVector::get(Inits);
+ }
+
return C;
}
@@ -2667,12 +2678,10 @@ ConstantEmitter::tryEmitPrivate(const APValue &Value, QualType DestType,
unsigned NumElts = NumRows * NumCols;
SmallVector<llvm::Constant *, 16> Inits(NumElts);
- bool IsRowMajor = isMatrixRowMajor(CGM.getLangOpts(), DestType);
-
for (unsigned Row = 0; Row != NumRows; ++Row) {
for (unsigned Col = 0; Col != NumCols; ++Col) {
const APValue &Elt = Value.getMatrixElt(Row, Col);
- unsigned Idx = MT->getFlattenedIndex(Row, Col, IsRowMajor);
+ unsigned Idx = MT->getColumnMajorFlattenedIndex(Row, Col);
if (Elt.isInt())
Inits[Idx] =
llvm::ConstantInt::get(CGM.getLLVMContext(), Elt.getInt());
diff --git a/clang/test/CodeGenHLSL/BasicFeatures/MatrixInitializerListOrder.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/MatrixInitializerListOrder.hlsl
index 97ebe1712e9c7..d5879d7cdd5b4 100644
--- a/clang/test/CodeGenHLSL/BasicFeatures/MatrixInitializerListOrder.hlsl
+++ b/clang/test/CodeGenHLSL/BasicFeatures/MatrixInitializerListOrder.hlsl
@@ -11,6 +11,17 @@
// The register value is reordered to col0=[1,4], col1=[2,5], col2=[3,6] =
// <1,4,2,5,3,6>. Row-major memory layout transposes that value at the store.
+constexpr float2x3 make_matrix() {
+ return float2x3(1, 2, 3, 4, 5, 6);
+}
+
+export float2x3 return_constexpr_matrix() {
+// CHECK-LABEL: define {{.*}} <6 x float> @_Z23return_constexpr_matrixv
+// CHECK: ret <6 x float> <float 1.000000e+00, float 4.000000e+00, float 2.000000e+00, float 5.000000e+00, float 3.000000e+00, float 6.000000e+00>
+ constexpr float2x3 value = make_matrix();
+ return value;
+}
+
export float test_row0_col2() {
// CHECK-LABEL: define {{.*}} float @_Z14test_row0_col2v
// COL-CHECK: store <6 x float> <float 1.000000e+00, float 4.000000e+00, float 2.000000e+00, float 5.000000e+00, float 3.000000e+00, float 6.000000e+00>
More information about the cfe-commits
mailing list