https://github.com/Icohedron updated https://github.com/llvm/llvm-project/pull/177486
>From d20c1a92d4df29f7cc4de826dc6a6408c93dcb1b Mon Sep 17 00:00:00 2001 From: Deric Cheung <[email protected]> Date: Thu, 22 Jan 2026 14:41:09 -0800 Subject: [PATCH 1/9] Make matrices initializable by a single vector and vice-versa --- clang/lib/Sema/SemaInit.cpp | 6 +- .../MatrixToAndFromVectorConstructors.hlsl | 91 +++++++++++++++++++ .../BuiltinMatrix/MatrixSplatErrors.hlsl | 5 - 3 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 clang/test/CodeGenHLSL/MatrixToAndFromVectorConstructors.hlsl diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index ff278bc7471bd..58dba9b3ffe30 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -6938,7 +6938,11 @@ void InitializationSequence::InitializeFrom(Sema &S, // For HLSL ext vector types we allow list initialization behavior for C++ // functional cast expressions which look like constructor syntax. This is // accomplished by converting initialization arguments to InitListExpr. - if (S.getLangOpts().HLSL && Args.size() > 1 && + bool IsMatToVecOrVecToMatInit = + Args.size() == 1 && + ((SourceType->isExtVectorType() && DestType->isConstantMatrixType()) || + (SourceType->isConstantMatrixType() && DestType->isExtVectorType())); + if (S.getLangOpts().HLSL && (IsMatToVecOrVecToMatInit || Args.size() > 1) && (DestType->isExtVectorType() || DestType->isConstantMatrixType()) && (SourceType.isNull() || !Context.hasSameUnqualifiedType(SourceType, DestType))) { diff --git a/clang/test/CodeGenHLSL/MatrixToAndFromVectorConstructors.hlsl b/clang/test/CodeGenHLSL/MatrixToAndFromVectorConstructors.hlsl new file mode 100644 index 0000000000000..f7a5cae6a22ff --- /dev/null +++ b/clang/test/CodeGenHLSL/MatrixToAndFromVectorConstructors.hlsl @@ -0,0 +1,91 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - %s | FileCheck %s + +// CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z2fnu11matrix_typeILm2ELm2EfE( +// CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[M:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[M_ADDR:%.*]] = alloca [4 x float], align 4 +// CHECK-NEXT: [[V:%.*]] = alloca <4 x float>, align 16 +// CHECK-NEXT: store <4 x float> [[M]], ptr [[M_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x float>, ptr [[M_ADDR]], align 4 +// CHECK-NEXT: [[MATRIXEXT:%.*]] = extractelement <4 x float> [[TMP0]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x float> poison, float [[MATRIXEXT]], i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr [[M_ADDR]], align 4 +// CHECK-NEXT: [[MATRIXEXT1:%.*]] = extractelement <4 x float> [[TMP1]], i32 1 +// CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x float> [[VECINIT]], float [[MATRIXEXT1]], i32 1 +// CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[M_ADDR]], align 4 +// CHECK-NEXT: [[MATRIXEXT3:%.*]] = extractelement <4 x float> [[TMP2]], i32 2 +// CHECK-NEXT: [[VECINIT4:%.*]] = insertelement <4 x float> [[VECINIT2]], float [[MATRIXEXT3]], i32 2 +// CHECK-NEXT: [[TMP3:%.*]] = load <4 x float>, ptr [[M_ADDR]], align 4 +// CHECK-NEXT: [[MATRIXEXT5:%.*]] = extractelement <4 x float> [[TMP3]], i32 3 +// CHECK-NEXT: [[VECINIT6:%.*]] = insertelement <4 x float> [[VECINIT4]], float [[MATRIXEXT5]], i32 3 +// CHECK-NEXT: store <4 x float> [[VECINIT6]], ptr [[V]], align 16 +// CHECK-NEXT: [[TMP4:%.*]] = load <4 x float>, ptr [[V]], align 16 +// CHECK-NEXT: ret <4 x float> [[TMP4]] +// +float4 fn(float2x2 m) { + float4 v = m; + return v; +m + +// CHECK-LABEL: define hidden noundef <2 x i32> @_Z3fn1Dv2_i( +// CHECK-SAME: <2 x i32> noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[V_ADDR:%.*]] = alloca <2 x i32>, align 8 +// CHECK-NEXT: store <2 x i32> [[V]], ptr [[V_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load <2 x i32>, ptr [[V_ADDR]], align 8 +// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <2 x i32> [[TMP0]], i64 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <2 x i32> poison, i32 [[VECEXT]], i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load <2 x i32>, ptr [[V_ADDR]], align 8 +// CHECK-NEXT: [[VECEXT1:%.*]] = extractelement <2 x i32> [[TMP1]], i64 1 +// CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <2 x i32> [[VECINIT]], i32 [[VECEXT1]], i32 1 +// CHECK-NEXT: ret <2 x i32> [[VECINIT2]] +// +int1x2 fn1(int2 v) { + return v; +} + +// CHECK-LABEL: define hidden noundef <3 x i1> @_Z3fn2Dv3_b( +// CHECK-SAME: <3 x i1> noundef [[B:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca <3 x i32>, align 16 +// CHECK-NEXT: [[TMP0:%.*]] = zext <3 x i1> [[B]] to <3 x i32> +// CHECK-NEXT: store <3 x i32> [[TMP0]], ptr [[B_ADDR]], align 16 +// CHECK-NEXT: [[TMP1:%.*]] = load <3 x i32>, ptr [[B_ADDR]], align 16 +// CHECK-NEXT: [[LOADEDV:%.*]] = trunc <3 x i32> [[TMP1]] to <3 x i1> +// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <3 x i1> [[LOADEDV]], i64 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <3 x i1> poison, i1 [[VECEXT]], i32 0 +// CHECK-NEXT: [[TMP2:%.*]] = load <3 x i32>, ptr [[B_ADDR]], align 16 +// CHECK-NEXT: [[LOADEDV1:%.*]] = trunc <3 x i32> [[TMP2]] to <3 x i1> +// CHECK-NEXT: [[VECEXT2:%.*]] = extractelement <3 x i1> [[LOADEDV1]], i64 1 +// CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <3 x i1> [[VECINIT]], i1 [[VECEXT2]], i32 1 +// CHECK-NEXT: [[TMP3:%.*]] = load <3 x i32>, ptr [[B_ADDR]], align 16 +// CHECK-NEXT: [[LOADEDV4:%.*]] = trunc <3 x i32> [[TMP3]] to <3 x i1> +// CHECK-NEXT: [[VECEXT5:%.*]] = extractelement <3 x i1> [[LOADEDV4]], i64 2 +// CHECK-NEXT: [[VECINIT6:%.*]] = insertelement <3 x i1> [[VECINIT3]], i1 [[VECEXT5]], i32 2 +// CHECK-NEXT: ret <3 x i1> [[VECINIT6]] +// +bool3x1 fn2(bool3 b) { + return b; +} + +// CHECK-LABEL: define hidden noundef <3 x i32> @_Z3fn3u11matrix_typeILm1ELm3EbE( +// CHECK-SAME: <3 x i1> noundef [[B:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca [3 x i32], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = zext <3 x i1> [[B]] to <3 x i32> +// CHECK-NEXT: store <3 x i32> [[TMP0]], ptr [[B_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = load <3 x i32>, ptr [[B_ADDR]], align 4 +// CHECK-NEXT: [[MATRIXEXT:%.*]] = extractelement <3 x i32> [[TMP1]], i32 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <3 x i32> poison, i32 [[MATRIXEXT]], i32 0 +// CHECK-NEXT: [[TMP2:%.*]] = load <3 x i32>, ptr [[B_ADDR]], align 4 +// CHECK-NEXT: [[MATRIXEXT1:%.*]] = extractelement <3 x i32> [[TMP2]], i32 1 +// CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <3 x i32> [[VECINIT]], i32 [[MATRIXEXT1]], i32 1 +// CHECK-NEXT: [[TMP3:%.*]] = load <3 x i32>, ptr [[B_ADDR]], align 4 +// CHECK-NEXT: [[MATRIXEXT3:%.*]] = extractelement <3 x i32> [[TMP3]], i32 2 +// CHECK-NEXT: [[VECINIT4:%.*]] = insertelement <3 x i32> [[VECINIT2]], i32 [[MATRIXEXT3]], i32 2 +// CHECK-NEXT: ret <3 x i32> [[VECINIT4]] +// +int3 fn3(bool1x3 b) { + return b; +} diff --git a/clang/test/SemaHLSL/Types/BuiltinMatrix/MatrixSplatErrors.hlsl b/clang/test/SemaHLSL/Types/BuiltinMatrix/MatrixSplatErrors.hlsl index 0c2e53d382180..5a726bb324b60 100644 --- a/clang/test/SemaHLSL/Types/BuiltinMatrix/MatrixSplatErrors.hlsl +++ b/clang/test/SemaHLSL/Types/BuiltinMatrix/MatrixSplatErrors.hlsl @@ -1,10 +1,5 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -std=hlsl202x -verify %s -void SplatOfVectortoMat(int4 V){ - int2x2 M = V; - // expected-error@-1 {{cannot initialize a variable of type 'int2x2' (aka 'matrix<int, 2, 2>') with an lvalue of type 'int4' (aka 'vector<int, 4>')}} -} - void SplatOfMattoMat(int4x3 N){ int4x4 M = N; // expected-error@-1 {{cannot initialize a variable of type 'matrix<[2 * ...], 4>' with an lvalue of type 'matrix<[2 * ...], 3>'}} >From d63e41724c526143e49f83689663a90414a69b84 Mon Sep 17 00:00:00 2001 From: Deric Cheung <[email protected]> Date: Thu, 22 Jan 2026 16:03:52 -0800 Subject: [PATCH 2/9] Check HLSL lang opt in HLSL-specific bool --- clang/lib/Sema/SemaInit.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 58dba9b3ffe30..b2bdf8e3e9d60 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -6938,11 +6938,11 @@ void InitializationSequence::InitializeFrom(Sema &S, // For HLSL ext vector types we allow list initialization behavior for C++ // functional cast expressions which look like constructor syntax. This is // accomplished by converting initialization arguments to InitListExpr. - bool IsMatToVecOrVecToMatInit = - Args.size() == 1 && + bool IsHLSLMatToVecOrVecToMatInit = + S.getLangOpts().HLSL && Args.size() == 1 && ((SourceType->isExtVectorType() && DestType->isConstantMatrixType()) || (SourceType->isConstantMatrixType() && DestType->isExtVectorType())); - if (S.getLangOpts().HLSL && (IsMatToVecOrVecToMatInit || Args.size() > 1) && + if (S.getLangOpts().HLSL && (IsHLSLMatToVecOrVecToMatInit || Args.size() > 1) && (DestType->isExtVectorType() || DestType->isConstantMatrixType()) && (SourceType.isNull() || !Context.hasSameUnqualifiedType(SourceType, DestType))) { >From debf088fa6ed2935369af7c8f0485e23bc9e9c91 Mon Sep 17 00:00:00 2001 From: Deric Cheung <[email protected]> Date: Thu, 22 Jan 2026 16:06:36 -0800 Subject: [PATCH 3/9] Fix typo in test --- clang/test/CodeGenHLSL/MatrixToAndFromVectorConstructors.hlsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/CodeGenHLSL/MatrixToAndFromVectorConstructors.hlsl b/clang/test/CodeGenHLSL/MatrixToAndFromVectorConstructors.hlsl index f7a5cae6a22ff..63db8ec9d7763 100644 --- a/clang/test/CodeGenHLSL/MatrixToAndFromVectorConstructors.hlsl +++ b/clang/test/CodeGenHLSL/MatrixToAndFromVectorConstructors.hlsl @@ -26,7 +26,7 @@ float4 fn(float2x2 m) { float4 v = m; return v; -m +} // CHECK-LABEL: define hidden noundef <2 x i32> @_Z3fn1Dv2_i( // CHECK-SAME: <2 x i32> noundef [[V:%.*]]) #[[ATTR0]] { >From cf27db9dc1e116bbdcf12286527772b863dcc366 Mon Sep 17 00:00:00 2001 From: Deric Cheung <[email protected]> Date: Thu, 22 Jan 2026 16:07:13 -0800 Subject: [PATCH 4/9] Apply clang-format --- clang/lib/Sema/SemaInit.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index b2bdf8e3e9d60..930da8783ab3b 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -6942,7 +6942,8 @@ void InitializationSequence::InitializeFrom(Sema &S, S.getLangOpts().HLSL && Args.size() == 1 && ((SourceType->isExtVectorType() && DestType->isConstantMatrixType()) || (SourceType->isConstantMatrixType() && DestType->isExtVectorType())); - if (S.getLangOpts().HLSL && (IsHLSLMatToVecOrVecToMatInit || Args.size() > 1) && + if (S.getLangOpts().HLSL && + (IsHLSLMatToVecOrVecToMatInit || Args.size() > 1) && (DestType->isExtVectorType() || DestType->isConstantMatrixType()) && (SourceType.isNull() || !Context.hasSameUnqualifiedType(SourceType, DestType))) { >From a9b3464bbeca0f00e1fa4632882da6c270983915 Mon Sep 17 00:00:00 2001 From: Deric Cheung <[email protected]> Date: Fri, 23 Jan 2026 14:43:12 -0800 Subject: [PATCH 5/9] Make test try both row and column major order matrices --- .../MatrixToAndFromVectorConstructors.hlsl | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/clang/test/CodeGenHLSL/MatrixToAndFromVectorConstructors.hlsl b/clang/test/CodeGenHLSL/MatrixToAndFromVectorConstructors.hlsl index 63db8ec9d7763..8438d50725a93 100644 --- a/clang/test/CodeGenHLSL/MatrixToAndFromVectorConstructors.hlsl +++ b/clang/test/CodeGenHLSL/MatrixToAndFromVectorConstructors.hlsl @@ -1,5 +1,5 @@ -// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - -fmatrix-memory-layout=column-major %s | FileCheck %s --check-prefixes=CHECK,COL-CHECK +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -disable-llvm-passes -emit-llvm -finclude-default-header -o - -fmatrix-memory-layout=row-major %s | FileCheck %s --check-prefixes=CHECK,ROW-CHECK // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z2fnu11matrix_typeILm2ELm2EfE( // CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[M:%.*]]) #[[ATTR0:[0-9]+]] { @@ -11,10 +11,12 @@ // CHECK-NEXT: [[MATRIXEXT:%.*]] = extractelement <4 x float> [[TMP0]], i32 0 // CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x float> poison, float [[MATRIXEXT]], i32 0 // CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr [[M_ADDR]], align 4 -// CHECK-NEXT: [[MATRIXEXT1:%.*]] = extractelement <4 x float> [[TMP1]], i32 1 +// COL-CHECK-NEXT: [[MATRIXEXT1:%.*]] = extractelement <4 x float> [[TMP1]], i32 1 +// ROW-CHECK-NEXT: [[MATRIXEXT1:%.*]] = extractelement <4 x float> [[TMP1]], i32 2 // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x float> [[VECINIT]], float [[MATRIXEXT1]], i32 1 // CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[M_ADDR]], align 4 -// CHECK-NEXT: [[MATRIXEXT3:%.*]] = extractelement <4 x float> [[TMP2]], i32 2 +// COL-CHECK-NEXT: [[MATRIXEXT3:%.*]] = extractelement <4 x float> [[TMP2]], i32 2 +// ROW-CHECK-NEXT: [[MATRIXEXT3:%.*]] = extractelement <4 x float> [[TMP2]], i32 1 // CHECK-NEXT: [[VECINIT4:%.*]] = insertelement <4 x float> [[VECINIT2]], float [[MATRIXEXT3]], i32 2 // CHECK-NEXT: [[TMP3:%.*]] = load <4 x float>, ptr [[M_ADDR]], align 4 // CHECK-NEXT: [[MATRIXEXT5:%.*]] = extractelement <4 x float> [[TMP3]], i32 3 @@ -28,6 +30,33 @@ float4 fn(float2x2 m) { return v; } +// CHECK-LABEL: define hidden noundef <4 x i32> @_Z2fnDv4_i( +// CHECK-SAME: <4 x i32> noundef [[V:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[V_ADDR:%.*]] = alloca <4 x i32>, align 16 +// CHECK-NEXT: [[M:%.*]] = alloca [4 x i32], align 4 +// CHECK-NEXT: store <4 x i32> [[V]], ptr [[V_ADDR]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, ptr [[V_ADDR]], align 16 +// CHECK-NEXT: [[VECEXT:%.*]] = extractelement <4 x i32> [[TMP0]], i64 0 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x i32> poison, i32 [[VECEXT]], i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr [[V_ADDR]], align 16 +// CHECK-NEXT: [[VECEXT1:%.*]] = extractelement <4 x i32> [[TMP1]], i64 2 +// CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x i32> [[VECINIT]], i32 [[VECEXT1]], i32 1 +// CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr [[V_ADDR]], align 16 +// CHECK-NEXT: [[VECEXT3:%.*]] = extractelement <4 x i32> [[TMP2]], i64 1 +// CHECK-NEXT: [[VECINIT4:%.*]] = insertelement <4 x i32> [[VECINIT2]], i32 [[VECEXT3]], i32 2 +// CHECK-NEXT: [[TMP3:%.*]] = load <4 x i32>, ptr [[V_ADDR]], align 16 +// CHECK-NEXT: [[VECEXT5:%.*]] = extractelement <4 x i32> [[TMP3]], i64 3 +// CHECK-NEXT: [[VECINIT6:%.*]] = insertelement <4 x i32> [[VECINIT4]], i32 [[VECEXT5]], i32 3 +// CHECK-NEXT: store <4 x i32> [[VECINIT6]], ptr [[M]], align 4 +// CHECK-NEXT: [[TMP4:%.*]] = load <4 x i32>, ptr [[M]], align 4 +// CHECK-NEXT: ret <4 x i32> [[TMP4]] +// +int2x2 fn(int4 v) { + int2x2 m = v; + return m; +} + // CHECK-LABEL: define hidden noundef <2 x i32> @_Z3fn1Dv2_i( // CHECK-SAME: <2 x i32> noundef [[V:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] >From 74ae3b6f88c832a39a16991222875352d32a192e Mon Sep 17 00:00:00 2001 From: Deric Cheung <[email protected]> Date: Mon, 26 Jan 2026 10:24:18 -0800 Subject: [PATCH 6/9] Move test into BasicFeatures folder --- .../{ => BasicFeatures}/MatrixToAndFromVectorConstructors.hlsl | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename clang/test/CodeGenHLSL/{ => BasicFeatures}/MatrixToAndFromVectorConstructors.hlsl (100%) diff --git a/clang/test/CodeGenHLSL/MatrixToAndFromVectorConstructors.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/MatrixToAndFromVectorConstructors.hlsl similarity index 100% rename from clang/test/CodeGenHLSL/MatrixToAndFromVectorConstructors.hlsl rename to clang/test/CodeGenHLSL/BasicFeatures/MatrixToAndFromVectorConstructors.hlsl >From 6bb3508ab12f65cbff36a3bcea7b22dda7df2008 Mon Sep 17 00:00:00 2001 From: Deric Cheung <[email protected]> Date: Mon, 26 Jan 2026 11:08:16 -0800 Subject: [PATCH 7/9] Add new vector-to-matrix sema error tests --- .../Types/BuiltinMatrix/MatrixSplatErrors.hlsl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/clang/test/SemaHLSL/Types/BuiltinMatrix/MatrixSplatErrors.hlsl b/clang/test/SemaHLSL/Types/BuiltinMatrix/MatrixSplatErrors.hlsl index 5a726bb324b60..fc3f8e7adc050 100644 --- a/clang/test/SemaHLSL/Types/BuiltinMatrix/MatrixSplatErrors.hlsl +++ b/clang/test/SemaHLSL/Types/BuiltinMatrix/MatrixSplatErrors.hlsl @@ -1,5 +1,15 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.6-library -finclude-default-header -std=hlsl202x -verify %s +void SplatOfUndersizedVectortoMat(int3 V){ + int2x2 M = V; + // expected-error@-1 {{too few initializers in list for type 'int2x2' (aka 'matrix<int, 2, 2>') (expected 4 but found 3)}} +} + +void SplatOfOversizedVectortoMat(int3 V){ + int1x2 M = V; + // expected-error@-1 {{too many initializers in list for type 'int1x2' (aka 'matrix<int, 1, 2>') (expected 2 but found 3)}} +} + void SplatOfMattoMat(int4x3 N){ int4x4 M = N; // expected-error@-1 {{cannot initialize a variable of type 'matrix<[2 * ...], 4>' with an lvalue of type 'matrix<[2 * ...], 3>'}} >From 8ea17833229b740383a4f65bad724fc72ccad936 Mon Sep 17 00:00:00 2001 From: Deric Cheung <[email protected]> Date: Mon, 2 Feb 2026 11:22:04 -0800 Subject: [PATCH 8/9] Fix test after change to matrix initialization list order in upstream --- .../BasicFeatures/MatrixToAndFromVectorConstructors.hlsl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/test/CodeGenHLSL/BasicFeatures/MatrixToAndFromVectorConstructors.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/MatrixToAndFromVectorConstructors.hlsl index 8438d50725a93..5b1cc2f4bd5c4 100644 --- a/clang/test/CodeGenHLSL/BasicFeatures/MatrixToAndFromVectorConstructors.hlsl +++ b/clang/test/CodeGenHLSL/BasicFeatures/MatrixToAndFromVectorConstructors.hlsl @@ -11,12 +11,12 @@ // CHECK-NEXT: [[MATRIXEXT:%.*]] = extractelement <4 x float> [[TMP0]], i32 0 // CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x float> poison, float [[MATRIXEXT]], i32 0 // CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, ptr [[M_ADDR]], align 4 -// COL-CHECK-NEXT: [[MATRIXEXT1:%.*]] = extractelement <4 x float> [[TMP1]], i32 1 -// ROW-CHECK-NEXT: [[MATRIXEXT1:%.*]] = extractelement <4 x float> [[TMP1]], i32 2 +// COL-CHECK-NEXT: [[MATRIXEXT1:%.*]] = extractelement <4 x float> [[TMP1]], i32 2 +// ROW-CHECK-NEXT: [[MATRIXEXT1:%.*]] = extractelement <4 x float> [[TMP1]], i32 1 // CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x float> [[VECINIT]], float [[MATRIXEXT1]], i32 1 // CHECK-NEXT: [[TMP2:%.*]] = load <4 x float>, ptr [[M_ADDR]], align 4 -// COL-CHECK-NEXT: [[MATRIXEXT3:%.*]] = extractelement <4 x float> [[TMP2]], i32 2 -// ROW-CHECK-NEXT: [[MATRIXEXT3:%.*]] = extractelement <4 x float> [[TMP2]], i32 1 +// COL-CHECK-NEXT: [[MATRIXEXT3:%.*]] = extractelement <4 x float> [[TMP2]], i32 1 +// ROW-CHECK-NEXT: [[MATRIXEXT3:%.*]] = extractelement <4 x float> [[TMP2]], i32 2 // CHECK-NEXT: [[VECINIT4:%.*]] = insertelement <4 x float> [[VECINIT2]], float [[MATRIXEXT3]], i32 2 // CHECK-NEXT: [[TMP3:%.*]] = load <4 x float>, ptr [[M_ADDR]], align 4 // CHECK-NEXT: [[MATRIXEXT5:%.*]] = extractelement <4 x float> [[TMP3]], i32 3 >From cf4ee3f42ffeeee928a782e4d0ab77dafb61505a Mon Sep 17 00:00:00 2001 From: Deric Cheung <[email protected]> Date: Tue, 17 Feb 2026 14:47:02 -0800 Subject: [PATCH 9/9] Replace complex boolean expression with a boolean lambda expression with early returns --- clang/lib/Sema/SemaInit.cpp | 42 +++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 930da8783ab3b..2e705a6c50be7 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -6938,15 +6938,39 @@ void InitializationSequence::InitializeFrom(Sema &S, // For HLSL ext vector types we allow list initialization behavior for C++ // functional cast expressions which look like constructor syntax. This is // accomplished by converting initialization arguments to InitListExpr. - bool IsHLSLMatToVecOrVecToMatInit = - S.getLangOpts().HLSL && Args.size() == 1 && - ((SourceType->isExtVectorType() && DestType->isConstantMatrixType()) || - (SourceType->isConstantMatrixType() && DestType->isExtVectorType())); - if (S.getLangOpts().HLSL && - (IsHLSLMatToVecOrVecToMatInit || Args.size() > 1) && - (DestType->isExtVectorType() || DestType->isConstantMatrixType()) && - (SourceType.isNull() || - !Context.hasSameUnqualifiedType(SourceType, DestType))) { + auto ShouldTryListInitialization = [&]() -> bool { + // Only try list initialization for HLSL. + if (!S.getLangOpts().HLSL) + return false; + + bool DestIsVec = DestType->isExtVectorType(); + bool DestIsMat = DestType->isConstantMatrixType(); + + // If the destination type is neither a vector nor a matrix, then don't try + // list initialization. + if (!DestIsVec && !DestIsMat) + return false; + + // If there is only a single source argument, then only try list + // initialization if initializing a matrix with a vector or vice versa. + if (Args.size() == 1) { + assert(!SourceType.isNull() && + "Source QualType should not be null when arg size is exactly 1"); + bool SourceIsVec = SourceType->isExtVectorType(); + bool SourceIsMat = SourceType->isConstantMatrixType(); + + if (DestIsMat && !SourceIsVec) + return false; + if (DestIsVec && !SourceIsMat) + return false; + } + + // Try list initialization if the source type is null or if the + // destination and source types differ. + return SourceType.isNull() || + !Context.hasSameUnqualifiedType(SourceType, DestType); + }; + if (ShouldTryListInitialization()) { InitListExpr *ILE = new (Context) InitListExpr(S.getASTContext(), Args.front()->getBeginLoc(), Args, Args.back()->getEndLoc()); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
