From 677283588763bbe9d603d997cea93e5e64f79875 Mon Sep 17 00:00:00 2001 From: Ashley Coleman Date: Mon, 17 Aug 2026 13:23:21 -0600 Subject: [PATCH 1/3] [SM6.10] LinAlg Validation: MatrixOuterProduct --- docs/DXIL.rst | 4 +- lib/DxilValidation/DxilValidation.cpp | 64 ++++++++++- lib/DxilValidation/DxilValidationUtils.cpp | 40 +++++++ lib/DxilValidation/DxilValidationUtils.h | 4 + .../builtins/matrixouterproduct/nominal.hlsl | 27 +++-- .../LinAlgMatrix/linalgmatrix-outerproduct.ll | 107 ++++++++++++++++++ utils/hct/hctdb.py | 12 +- 7 files changed, 241 insertions(+), 17 deletions(-) create mode 100644 tools/clang/test/LitDXILValidation/LinAlgMatrix/linalgmatrix-outerproduct.ll diff --git a/docs/DXIL.rst b/docs/DXIL.rst index ba0de6e739..9eb3049dae 100644 --- a/docs/DXIL.rst +++ b/docs/DXIL.rst @@ -3219,7 +3219,6 @@ INSTR.LINALGMATRIXLOADTHREADREQUIRESBAB Loading matrix with Thread INSTR.LINALGMATRIXMATRIXKDIMMUSTMATCH K dim of A matrix '%0' must match K dim of B matrix '%1'. %2 != %3. INSTR.LINALGMATRIXMATRIXRESDIMMUSTMATCH %0 matrix dimension '%1' must match A.MxB.N '%2'. INSTR.LINALGMATRIXNOTEXACTMATCH %0 matrix '%1' must exactly match %2 matrix '%3'. -INSTR.LINALGMATRIXOUTPUTBIASVECMISMATCH Output vector element type '%0' must match bias vector element type '%1' INSTR.LINALGMATRIXREQUIRESLAYOUT2 %0 requires layout %1 or %2. INSTR.LINALGMATRIXREQUIRESRWBAB %0 requires RWByteAddressBuffer. INSTR.LINALGMATRIXSCOPEMISMATCH %0 matrix scope '%1' does not match expected scope %2. @@ -3230,6 +3229,9 @@ INSTR.LINALGMATRIXSCOPEREQLAYOUT2 %0 matrix with scope '%1' INSTR.LINALGMATRIXUNSIGNEDFLOATTYPENOTALLOWED Float-like type '%0' must be signed INSTR.LINALGMATRIXUSEMISMATCH %0 matrix use '%1' does not match expected use %2. INSTR.LINALGMATRIXUSEMISMATCH2 %0 matrix use '%1' does not match expected use %2 or %3. +INSTR.LINALGMATRIXVECELEMENTTYPEMISMATCH %0 vector element type '%1' must match %2 vector element type '%3' +INSTR.LINALGMATRIXVECTORTYPEMUSTMATCH %0 vector element type '%1' must match %2 matrix element type '%3'. +INSTR.LINALGMATRIXVECTORTYPEMUSTMATCHPACKED %0 vector element type '%1' must be i32 for %2 matrix with non-native element type '%3'. INSTR.LINALGMETADATAMISSING %0 matrix must have well-formed metadata. INSTR.MAYREORDERTHREADUNDEFCOHERENCEHINTPARAM Use of undef coherence hint or num coherence hint bits in MaybeReorderThread. INSTR.MINPRECISIONNOTPRECISE Instructions marked precise may not refer to minprecision values. diff --git a/lib/DxilValidation/DxilValidation.cpp b/lib/DxilValidation/DxilValidation.cpp index ee047af974..53332272fd 100644 --- a/lib/DxilValidation/DxilValidation.cpp +++ b/lib/DxilValidation/DxilValidation.cpp @@ -1311,8 +1311,8 @@ static void ValidateLinAlgMatVecMulAdd(CallInst *CI, // Bias element type must match output element type if (BiasVecTy->getElementType() != OutputVecTy->getElementType()) ValCtx.EmitInstrFormatError( - CI, ValidationRule::InstrLinAlgMatrixOutputBiasVecMismatch, - {TypeToString(OutputVecTy->getElementType()), + CI, ValidationRule::InstrLinAlgMatrixVecElementTypeMismatch, + {"Output", TypeToString(OutputVecTy->getElementType()), "bias", TypeToString(BiasVecTy->getElementType())}); } @@ -1660,6 +1660,66 @@ static void ValidateLinAlgMatrixOuterProduct(CallInst *CI, ValidationContext &ValCtx) { ValidateLinAlgOpReturnMatrix(CI, ValCtx); ValidateLinAlgOpParameters(CI, ValCtx); + DxilInst_LinAlgMatrixOuterProduct Op(CI); + VectorType *AVecTy = cast(Op.get_vectorA()->getType()); + VectorType *BVecTy = cast(Op.get_vectorB()->getType()); + std::optional RetMat = + GetCheckedLATT(CI->getType(), ValCtx); + if (!RetMat) + return; + + // Matrix must be thread scope + if (RetMat->Scope != DXIL::MatrixScope::Thread) + ValCtx.EmitInstrFormatError( + CI, ValidationRule::InstrLinAlgMatrixScopeMismatch, + {"Return", MatrixScopeToString(RetMat->Scope), "Thread"}); + + // Matrix must be accumulator use + if (RetMat->Use != DXIL::MatrixUse::Accumulator) + ValCtx.EmitInstrFormatError( + CI, ValidationRule::InstrLinAlgMatrixUseMismatch, + {"Return", MatrixUseToString(RetMat->Use), "Accumulator"}); + + unsigned ElementsPerScalar = ComponentTypeElementsPerScalar(RetMat->Type); + + // M dim = length of vecA * number of matrix elements that fit in each scalar + unsigned M = AVecTy->getNumElements() * ElementsPerScalar; + + // N dim = length of vecB * number of matrix elements that fit in each scalar + unsigned N = BVecTy->getNumElements() * ElementsPerScalar; + + // Matrix must be M*N dim + if (RetMat->M != M || RetMat->N != N) + ValCtx.EmitInstrFormatError( + CI, ValidationRule::InstrLinAlgMatrix2PartsMustMatch, + {"Return", "dimension", + std::to_string(RetMat->M) + "x" + std::to_string(RetMat->N), "derived", + "dimension", std::to_string(M) + "x" + std::to_string(N)}); + + // element type of vecA and vecB must be the same + if (AVecTy->getElementType() != BVecTy->getElementType()) + ValCtx.EmitInstrFormatError( + CI, ValidationRule::InstrLinAlgMatrixVecElementTypeMismatch, + {"A", TypeToString(AVecTy->getElementType()), "B", + TypeToString(BVecTy->getElementType())}); + + bool IsNativeMat = IsComponentTypeNative(RetMat->Type); + + // If the matrix element type is native then the vec element type must match + if (IsNativeMat && + !IsComponentTypeSameNativeType(RetMat->Type, AVecTy->getElementType())) + ValCtx.EmitInstrFormatError( + CI, ValidationRule::InstrLinAlgMatrixVectorTypeMustMatch, + {"A", TypeToString(AVecTy->getElementType()), "return", + ComponentTypeToString(RetMat->Type)}); + + // If the matrix element type is non-native then vector element type must be + // i32 + if (!IsNativeMat && !AVecTy->getElementType()->isIntegerTy(32)) + ValCtx.EmitInstrFormatError( + CI, ValidationRule::InstrLinAlgMatrixVectorTypeMustMatchPacked, + {"A", TypeToString(AVecTy->getElementType()), "return", + ComponentTypeToString(RetMat->Type)}); } static void ValidateLinAlgMatrixLoadFromDescriptor(CallInst *CI, diff --git a/lib/DxilValidation/DxilValidationUtils.cpp b/lib/DxilValidation/DxilValidationUtils.cpp index 73f52c763c..e0b4071388 100644 --- a/lib/DxilValidation/DxilValidationUtils.cpp +++ b/lib/DxilValidation/DxilValidationUtils.cpp @@ -724,4 +724,44 @@ std::string TypeToString(llvm::Type *Ty) { return OS.str(); } +bool IsComponentTypeSameNativeType(DXIL::ComponentType CT, llvm::Type *Ty) { + switch (CT) { + case DXIL::ComponentType::I16: + case DXIL::ComponentType::U16: + return Ty->isIntegerTy(16); + case DXIL::ComponentType::I32: + case DXIL::ComponentType::U32: + return Ty->isIntegerTy(32); + case DXIL::ComponentType::I64: + case DXIL::ComponentType::U64: + return Ty->isIntegerTy(64); + case DXIL::ComponentType::F16: + return Ty->isHalfTy(); + case DXIL::ComponentType::F32: + return Ty->isFloatTy(); + case DXIL::ComponentType::F64: + return Ty->isDoubleTy(); + // All other CTs cannot be natively represented in a vector + default: + return false; + } +} + +bool IsComponentTypeNative(DXIL::ComponentType CT) { + switch (CT) { + case DXIL::ComponentType::I16: + case DXIL::ComponentType::U16: + case DXIL::ComponentType::I32: + case DXIL::ComponentType::U32: + case DXIL::ComponentType::I64: + case DXIL::ComponentType::U64: + case DXIL::ComponentType::F16: + case DXIL::ComponentType::F32: + case DXIL::ComponentType::F64: + return true; + default: + return false; + } +} + } // namespace hlsl diff --git a/lib/DxilValidation/DxilValidationUtils.h b/lib/DxilValidation/DxilValidationUtils.h index b9c09d7bff..e854ad97c5 100644 --- a/lib/DxilValidation/DxilValidationUtils.h +++ b/lib/DxilValidation/DxilValidationUtils.h @@ -165,4 +165,8 @@ llvm::StringRef MatrixUseToString(DXIL::MatrixUse MU); llvm::StringRef MatrixLayoutToString(DXIL::MatrixLayout ML); std::string TypeToString(llvm::Type *Ty); + +bool IsComponentTypeSameNativeType(DXIL::ComponentType CT, llvm::Type *Ty); + +bool IsComponentTypeNative(DXIL::ComponentType CT); } // namespace hlsl diff --git a/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixouterproduct/nominal.hlsl b/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixouterproduct/nominal.hlsl index 8b478f2980..338499fbde 100644 --- a/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixouterproduct/nominal.hlsl +++ b/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixouterproduct/nominal.hlsl @@ -8,34 +8,37 @@ void main() { float4 lhs1 = {1,2,3,4}; float4 rhs1 = {4,3,2,1}; + // Matrix + __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(9, 4, 4, 2, 0)]] mat1; - // CHECK: call %dx.types.LinAlgMatrixC2M2N2U2S2 @dx.op.linAlgMatrixOuterProduct.mC2M2N2U2S2.v4f32.v4f32 + // CHECK: call %dx.types.LinAlgMatrixC9M4N4U2S0 @dx.op.linAlgMatrixOuterProduct.mC9M4N4U2S0.v4f32.v4f32 // CHECK-SAME: (i32 -2147483619, <4 x float> {{.*}}, <4 x float> {{.*}}) ; LinAlgMatrixOuterProduct(vectorA,vectorB) - // CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC2M2N2U2S2*, <4 x float>, <4 x float>)" - // CHECK2: (i32 417, %dx.types.LinAlgMatrixC2M2N2U2S2* {{.*}}, <4 x float> {{.*}}, <4 x float> {{.*}}) - __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(2, 2, 2, 2, 2)]] mat1; + // CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC9M4N4U2S0*, <4 x float>, <4 x float>)" + // CHECK2: (i32 417, %dx.types.LinAlgMatrixC9M4N4U2S0* {{.*}}, <4 x float> {{.*}}, <4 x float> {{.*}}) __builtin_LinAlg_MatrixOuterProduct(mat1, lhs1, rhs1); double4 lhs2 = {1,2,3,4}; double4 rhs2 = {4,3,2,1}; + // Matrix + __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(10, 4, 4, 2, 0)]] mat2; - // CHECK: call %dx.types.LinAlgMatrixC2M2N2U2S2 @dx.op.linAlgMatrixOuterProduct.mC2M2N2U2S2.v4f64.v4f64 + // CHECK: call %dx.types.LinAlgMatrixC10M4N4U2S0 @dx.op.linAlgMatrixOuterProduct.mC10M4N4U2S0.v4f64.v4f64 // CHECK-SAME: (i32 -2147483619, <4 x double> {{.*}}, <4 x double> {{.*}}) ; LinAlgMatrixOuterProduct(vectorA,vectorB) - // CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC2M2N2U2S2*, <4 x double>, <4 x double>)" - // CHECK2: (i32 417, %dx.types.LinAlgMatrixC2M2N2U2S2* {{.*}}, <4 x double> {{.*}}, <4 x double> {{.*}}) - __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(2, 2, 2, 2, 2)]] mat2; + // CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC10M4N4U2S0*, <4 x double>, <4 x double>)" + // CHECK2: (i32 417, %dx.types.LinAlgMatrixC10M4N4U2S0* {{.*}}, <4 x double> {{.*}}, <4 x double> {{.*}}) __builtin_LinAlg_MatrixOuterProduct(mat2, lhs2, rhs2); vector lhs3 = {1,2,3,4}; vector rhs3 = {4,3,2,1}; + // Matrix + __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(6, 4, 4, 2, 0)]] mat3; - // CHECK: call %dx.types.LinAlgMatrixC2M2N2U2S2 @dx.op.linAlgMatrixOuterProduct.mC2M2N2U2S2.v4i64.v4i64 + // CHECK: call %dx.types.LinAlgMatrixC6M4N4U2S0 @dx.op.linAlgMatrixOuterProduct.mC6M4N4U2S0.v4i64.v4i64 // CHECK-SAME: (i32 -2147483619, <4 x i64> {{.*}}, <4 x i64> {{.*}}) ; LinAlgMatrixOuterProduct(vectorA,vectorB) - // CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC2M2N2U2S2*, <4 x i64>, <4 x i64>)" - // CHECK2: (i32 417, %dx.types.LinAlgMatrixC2M2N2U2S2* {{.*}}, <4 x i64> {{.*}}, <4 x i64> {{.*}}) - __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(2, 2, 2, 2, 2)]] mat3; + // CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC6M4N4U2S0*, <4 x i64>, <4 x i64>)" + // CHECK2: (i32 417, %dx.types.LinAlgMatrixC6M4N4U2S0* {{.*}}, <4 x i64> {{.*}}, <4 x i64> {{.*}}) __builtin_LinAlg_MatrixOuterProduct(mat3, lhs3, rhs3); } diff --git a/tools/clang/test/LitDXILValidation/LinAlgMatrix/linalgmatrix-outerproduct.ll b/tools/clang/test/LitDXILValidation/LinAlgMatrix/linalgmatrix-outerproduct.ll new file mode 100644 index 0000000000..0804c7dc1e --- /dev/null +++ b/tools/clang/test/LitDXILValidation/LinAlgMatrix/linalgmatrix-outerproduct.ll @@ -0,0 +1,107 @@ +; REQUIRES: dxil-1-10 +; RUN: not %dxv %s 2>&1 | FileCheck %s +target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-ms-dx" + +%dx.types.LinAlgMatrixC8M8N8U2S0 = type { i8* } +%dx.types.LinAlgMatrixC21M8N8U2S0 = type { i8* } +%dx.types.LinAlgMatrixC8M8N8U2S1 = type { i8* } +%dx.types.LinAlgMatrixC8M8N8U1S0 = type { i8* } +%dx.types.LinAlgMatrixC8M16N16U2S0 = type { i8* } +%dx.types.LinAlgMatrixC4M8N8U2S0 = type { i8* } + +define void @main() { + ; okay + %1 = call %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + + ; okay + %2 = call %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v2i32.v2i32(i32 -2147483619, <2 x i32> , <2 x i32> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + +; CHECK: Function: main: error: Return matrix scope 'Wave' does not match expected scope Thread. +; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S1.v8f16.v8f16 + %3 = call %dx.types.LinAlgMatrixC8M8N8U2S1 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S1.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + +; CHECK-NEXT: Function: main: error: Return matrix use 'B' does not match expected use Accumulator. +; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M8N8U1S0.v8f16.v8f16 + %4 = call %dx.types.LinAlgMatrixC8M8N8U1S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U1S0.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + +; CHECK-NEXT: Function: main: error: Return matrix dimension '16x16' must match derived matrix dimension '8x8'. +; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M16N16U2S0.v8f16.v8f16 + %5 = call %dx.types.LinAlgMatrixC8M16N16U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M16N16U2S0.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + +; CHECK-NEXT: Function: main: error: Return matrix dimension '8x8' must match derived matrix dimension '32x32'. +; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v8i32.v8i32 + %6 = call %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v8i32.v8i32(i32 -2147483619, <8 x i32> , <8 x i32> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + +; CHECK-NEXT: Function: main: error: A vector element type 'half' must match B vector element type 'i32' +; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8i32 + %7 = call %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8i32(i32 -2147483619, <8 x half> , <8 x i32> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + +; CHECK-NEXT: Function: main: error: A vector element type 'half' must match return matrix element type 'I32'. +; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC4M8N8U2S0.v8f16.v8f16 + %8 = call %dx.types.LinAlgMatrixC4M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC4M8N8U2S0.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + +; CHECK-NEXT: Function: main: error: A vector element type 'i32' must match return matrix element type 'F16'. +; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8i32.v8i32 + %9 = call %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8i32.v8i32(i32 -2147483619, <8 x i32> , <8 x i32> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + +; CHECK-NEXT: Function: main: error: A vector element type 'half' must be i32 for return matrix with non-native element type 'F8_E4M3FN'. +; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v2f16.v2f16 + %10 = call %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v2f16.v2f16(i32 -2147483619, <2 x half> , <2 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + +; CHECK-NEXT: Validation failed. + ret void +} + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8f16(i32, <8 x half>, <8 x half>) #0 + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v2i32.v2i32(i32, <2 x i32>, <2 x i32>) #0 + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC8M8N8U2S1 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S1.v8f16.v8f16(i32, <8 x half>, <8 x half>) #0 + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC8M8N8U1S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U1S0.v8f16.v8f16(i32, <8 x half>, <8 x half>) #0 + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC8M16N16U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M16N16U2S0.v8f16.v8f16(i32, <8 x half>, <8 x half>) #0 + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v8i32.v8i32(i32, <8 x i32>, <8 x i32>) #0 + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8i32(i32, <8 x half>, <8 x i32>) #0 + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC4M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC4M8N8U2S0.v8f16.v8f16(i32, <8 x half>, <8 x half>) #0 + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8i32.v8i32(i32, <8 x i32>, <8 x i32>) #0 + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v2f16.v2f16(i32, <2 x half>, <2 x half>) #0 + +attributes #0 = { nounwind } + +!dx.targetTypes = !{!0, !1, !2, !3, !4, !5} +!llvm.ident = !{!6} +!dx.version = !{!7} +!dx.valver = !{!7} +!dx.shaderModel = !{!8} +!dx.entryPoints = !{!9} + +!0 = !{%dx.types.LinAlgMatrixC8M8N8U2S0 undef, i32 8, i32 8, i32 8, i32 2, i32 0} +!1 = !{%dx.types.LinAlgMatrixC8M8N8U2S1 undef, i32 8, i32 8, i32 8, i32 2, i32 1} +!2 = !{%dx.types.LinAlgMatrixC8M8N8U1S0 undef, i32 8, i32 8, i32 8, i32 1, i32 0} +!3 = !{%dx.types.LinAlgMatrixC8M16N16U2S0 undef, i32 8, i32 16, i32 16, i32 2, i32 0} +!4 = !{%dx.types.LinAlgMatrixC4M8N8U2S0 undef, i32 4, i32 8, i32 8, i32 2, i32 0} +!5 = !{%dx.types.LinAlgMatrixC21M8N8U2S0 undef, i32 21, i32 8, i32 8, i32 2, i32 0} +!6 = !{!"dxc(private) 1.9.0.5459 (linalg-vali-matrixouterproduct, bd6c0b684-dirty)"} +!7 = !{i32 1, i32 10} +!8 = !{!"cs", i32 6, i32 10} +!9 = !{void ()* @main, !"main", null, null, !10} +!10 = !{i32 0, i64 8388608, i32 4, !11} +!11 = !{i32 1, i32 1, i32 1} + diff --git a/utils/hct/hctdb.py b/utils/hct/hctdb.py index 2597402dea..0d005dfa90 100644 --- a/utils/hct/hctdb.py +++ b/utils/hct/hctdb.py @@ -8690,8 +8690,8 @@ def build_valrules(self): "%0 vector size '%1' must be %2 for input matrix with K '%3' and Type '%4'", ) self.add_valrule( - "Instr.LinAlgMatrixOutputBiasVecMismatch", - "Output vector element type '%0' must match bias vector element type '%1'", + "Instr.LinAlgMatrixVecElementTypeMismatch", + "%0 vector element type '%1' must match %2 vector element type '%3'", ) self.add_valrule( "Instr.LinAlgMatrixUnsignedFloatTypeNotAllowed", @@ -8729,6 +8729,14 @@ def build_valrules(self): "Instr.LinAlgMatrixMatrixResDimMustMatch", "%0 matrix dimension '%1' must match A.MxB.N '%2'.", ) + self.add_valrule( + "Instr.LinAlgMatrixVectorTypeMustMatch", + "%0 vector element type '%1' must match %2 matrix element type '%3'.", + ) + self.add_valrule( + "Instr.LinAlgMatrixVectorTypeMustMatchPacked", + "%0 vector element type '%1' must be i32 for %2 matrix with non-native element type '%3'." + ) # Some legacy rules: # - space is only supported for shader targets 5.1 and higher From edf3e9949431fb7d106c452dd86b47857eb561a8 Mon Sep 17 00:00:00 2001 From: Ashley Coleman Date: Wed, 19 Aug 2026 18:15:44 -0600 Subject: [PATCH 2/3] Update rules to match new validation rules --- docs/DXIL.rst | 2 - lib/DxilValidation/DxilValidation.cpp | 28 ++-------- lib/DxilValidation/DxilValidationUtils.cpp | 40 -------------- lib/DxilValidation/DxilValidationUtils.h | 4 -- .../LinAlgMatrix/linalgmatrix-outerproduct.ll | 54 +++++-------------- utils/hct/hctdb.py | 8 --- 6 files changed, 17 insertions(+), 119 deletions(-) diff --git a/docs/DXIL.rst b/docs/DXIL.rst index 9eb3049dae..74acdd51fa 100644 --- a/docs/DXIL.rst +++ b/docs/DXIL.rst @@ -3230,8 +3230,6 @@ INSTR.LINALGMATRIXUNSIGNEDFLOATTYPENOTALLOWED Float-like type '%0' must INSTR.LINALGMATRIXUSEMISMATCH %0 matrix use '%1' does not match expected use %2. INSTR.LINALGMATRIXUSEMISMATCH2 %0 matrix use '%1' does not match expected use %2 or %3. INSTR.LINALGMATRIXVECELEMENTTYPEMISMATCH %0 vector element type '%1' must match %2 vector element type '%3' -INSTR.LINALGMATRIXVECTORTYPEMUSTMATCH %0 vector element type '%1' must match %2 matrix element type '%3'. -INSTR.LINALGMATRIXVECTORTYPEMUSTMATCHPACKED %0 vector element type '%1' must be i32 for %2 matrix with non-native element type '%3'. INSTR.LINALGMETADATAMISSING %0 matrix must have well-formed metadata. INSTR.MAYREORDERTHREADUNDEFCOHERENCEHINTPARAM Use of undef coherence hint or num coherence hint bits in MaybeReorderThread. INSTR.MINPRECISIONNOTPRECISE Instructions marked precise may not refer to minprecision values. diff --git a/lib/DxilValidation/DxilValidation.cpp b/lib/DxilValidation/DxilValidation.cpp index 53332272fd..3ae2446132 100644 --- a/lib/DxilValidation/DxilValidation.cpp +++ b/lib/DxilValidation/DxilValidation.cpp @@ -1680,13 +1680,11 @@ static void ValidateLinAlgMatrixOuterProduct(CallInst *CI, CI, ValidationRule::InstrLinAlgMatrixUseMismatch, {"Return", MatrixUseToString(RetMat->Use), "Accumulator"}); - unsigned ElementsPerScalar = ComponentTypeElementsPerScalar(RetMat->Type); + // M dim must be length of vecA + unsigned M = AVecTy->getNumElements(); - // M dim = length of vecA * number of matrix elements that fit in each scalar - unsigned M = AVecTy->getNumElements() * ElementsPerScalar; - - // N dim = length of vecB * number of matrix elements that fit in each scalar - unsigned N = BVecTy->getNumElements() * ElementsPerScalar; + // N dim must be length of vecB + unsigned N = BVecTy->getNumElements(); // Matrix must be M*N dim if (RetMat->M != M || RetMat->N != N) @@ -1702,24 +1700,6 @@ static void ValidateLinAlgMatrixOuterProduct(CallInst *CI, CI, ValidationRule::InstrLinAlgMatrixVecElementTypeMismatch, {"A", TypeToString(AVecTy->getElementType()), "B", TypeToString(BVecTy->getElementType())}); - - bool IsNativeMat = IsComponentTypeNative(RetMat->Type); - - // If the matrix element type is native then the vec element type must match - if (IsNativeMat && - !IsComponentTypeSameNativeType(RetMat->Type, AVecTy->getElementType())) - ValCtx.EmitInstrFormatError( - CI, ValidationRule::InstrLinAlgMatrixVectorTypeMustMatch, - {"A", TypeToString(AVecTy->getElementType()), "return", - ComponentTypeToString(RetMat->Type)}); - - // If the matrix element type is non-native then vector element type must be - // i32 - if (!IsNativeMat && !AVecTy->getElementType()->isIntegerTy(32)) - ValCtx.EmitInstrFormatError( - CI, ValidationRule::InstrLinAlgMatrixVectorTypeMustMatchPacked, - {"A", TypeToString(AVecTy->getElementType()), "return", - ComponentTypeToString(RetMat->Type)}); } static void ValidateLinAlgMatrixLoadFromDescriptor(CallInst *CI, diff --git a/lib/DxilValidation/DxilValidationUtils.cpp b/lib/DxilValidation/DxilValidationUtils.cpp index e0b4071388..73f52c763c 100644 --- a/lib/DxilValidation/DxilValidationUtils.cpp +++ b/lib/DxilValidation/DxilValidationUtils.cpp @@ -724,44 +724,4 @@ std::string TypeToString(llvm::Type *Ty) { return OS.str(); } -bool IsComponentTypeSameNativeType(DXIL::ComponentType CT, llvm::Type *Ty) { - switch (CT) { - case DXIL::ComponentType::I16: - case DXIL::ComponentType::U16: - return Ty->isIntegerTy(16); - case DXIL::ComponentType::I32: - case DXIL::ComponentType::U32: - return Ty->isIntegerTy(32); - case DXIL::ComponentType::I64: - case DXIL::ComponentType::U64: - return Ty->isIntegerTy(64); - case DXIL::ComponentType::F16: - return Ty->isHalfTy(); - case DXIL::ComponentType::F32: - return Ty->isFloatTy(); - case DXIL::ComponentType::F64: - return Ty->isDoubleTy(); - // All other CTs cannot be natively represented in a vector - default: - return false; - } -} - -bool IsComponentTypeNative(DXIL::ComponentType CT) { - switch (CT) { - case DXIL::ComponentType::I16: - case DXIL::ComponentType::U16: - case DXIL::ComponentType::I32: - case DXIL::ComponentType::U32: - case DXIL::ComponentType::I64: - case DXIL::ComponentType::U64: - case DXIL::ComponentType::F16: - case DXIL::ComponentType::F32: - case DXIL::ComponentType::F64: - return true; - default: - return false; - } -} - } // namespace hlsl diff --git a/lib/DxilValidation/DxilValidationUtils.h b/lib/DxilValidation/DxilValidationUtils.h index e854ad97c5..b9c09d7bff 100644 --- a/lib/DxilValidation/DxilValidationUtils.h +++ b/lib/DxilValidation/DxilValidationUtils.h @@ -165,8 +165,4 @@ llvm::StringRef MatrixUseToString(DXIL::MatrixUse MU); llvm::StringRef MatrixLayoutToString(DXIL::MatrixLayout ML); std::string TypeToString(llvm::Type *Ty); - -bool IsComponentTypeSameNativeType(DXIL::ComponentType CT, llvm::Type *Ty); - -bool IsComponentTypeNative(DXIL::ComponentType CT); } // namespace hlsl diff --git a/tools/clang/test/LitDXILValidation/LinAlgMatrix/linalgmatrix-outerproduct.ll b/tools/clang/test/LitDXILValidation/LinAlgMatrix/linalgmatrix-outerproduct.ll index 0804c7dc1e..256162be1c 100644 --- a/tools/clang/test/LitDXILValidation/LinAlgMatrix/linalgmatrix-outerproduct.ll +++ b/tools/clang/test/LitDXILValidation/LinAlgMatrix/linalgmatrix-outerproduct.ll @@ -15,41 +15,25 @@ define void @main() { %1 = call %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) ; okay - %2 = call %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v2i32.v2i32(i32 -2147483619, <2 x i32> , <2 x i32> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + %2 = call %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) -; CHECK: Function: main: error: Return matrix scope 'Wave' does not match expected scope Thread. -; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S1.v8f16.v8f16 + ; CHECK: Function: main: error: Return matrix scope 'Wave' does not match expected scope Thread. + ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S1.v8f16.v8f16 %3 = call %dx.types.LinAlgMatrixC8M8N8U2S1 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S1.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) -; CHECK-NEXT: Function: main: error: Return matrix use 'B' does not match expected use Accumulator. -; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M8N8U1S0.v8f16.v8f16 + ; CHECK-NEXT: Function: main: error: Return matrix use 'B' does not match expected use Accumulator. + ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M8N8U1S0.v8f16.v8f16 %4 = call %dx.types.LinAlgMatrixC8M8N8U1S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U1S0.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) -; CHECK-NEXT: Function: main: error: Return matrix dimension '16x16' must match derived matrix dimension '8x8'. -; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M16N16U2S0.v8f16.v8f16 + ; CHECK-NEXT: Function: main: error: Return matrix dimension '16x16' must match derived matrix dimension '8x8'. + ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M16N16U2S0.v8f16.v8f16 %5 = call %dx.types.LinAlgMatrixC8M16N16U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M16N16U2S0.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) -; CHECK-NEXT: Function: main: error: Return matrix dimension '8x8' must match derived matrix dimension '32x32'. -; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v8i32.v8i32 - %6 = call %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v8i32.v8i32(i32 -2147483619, <8 x i32> , <8 x i32> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + ; CHECK-NEXT: Function: main: error: A vector element type 'half' must match B vector element type 'i32' + ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8i32 + %6 = call %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8i32(i32 -2147483619, <8 x half> , <8 x i32> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) -; CHECK-NEXT: Function: main: error: A vector element type 'half' must match B vector element type 'i32' -; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8i32 - %7 = call %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8i32(i32 -2147483619, <8 x half> , <8 x i32> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) - -; CHECK-NEXT: Function: main: error: A vector element type 'half' must match return matrix element type 'I32'. -; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC4M8N8U2S0.v8f16.v8f16 - %8 = call %dx.types.LinAlgMatrixC4M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC4M8N8U2S0.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) - -; CHECK-NEXT: Function: main: error: A vector element type 'i32' must match return matrix element type 'F16'. -; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8i32.v8i32 - %9 = call %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8i32.v8i32(i32 -2147483619, <8 x i32> , <8 x i32> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) - -; CHECK-NEXT: Function: main: error: A vector element type 'half' must be i32 for return matrix with non-native element type 'F8_E4M3FN'. -; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v2f16.v2f16 - %10 = call %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v2f16.v2f16(i32 -2147483619, <2 x half> , <2 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) - -; CHECK-NEXT: Validation failed. + ; CHECK-NEXT: Validation failed. ret void } @@ -57,7 +41,7 @@ define void @main() { declare %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8f16(i32, <8 x half>, <8 x half>) #0 ; Function Attrs: nounwind -declare %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v2i32.v2i32(i32, <2 x i32>, <2 x i32>) #0 +declare %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v8f16.v8f16(i32, <8 x half>, <8 x half>) #0 ; Function Attrs: nounwind declare %dx.types.LinAlgMatrixC8M8N8U2S1 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S1.v8f16.v8f16(i32, <8 x half>, <8 x half>) #0 @@ -68,21 +52,9 @@ declare %dx.types.LinAlgMatrixC8M8N8U1S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8 ; Function Attrs: nounwind declare %dx.types.LinAlgMatrixC8M16N16U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M16N16U2S0.v8f16.v8f16(i32, <8 x half>, <8 x half>) #0 -; Function Attrs: nounwind -declare %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v8i32.v8i32(i32, <8 x i32>, <8 x i32>) #0 - ; Function Attrs: nounwind declare %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8i32(i32, <8 x half>, <8 x i32>) #0 -; Function Attrs: nounwind -declare %dx.types.LinAlgMatrixC4M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC4M8N8U2S0.v8f16.v8f16(i32, <8 x half>, <8 x half>) #0 - -; Function Attrs: nounwind -declare %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8i32.v8i32(i32, <8 x i32>, <8 x i32>) #0 - -; Function Attrs: nounwind -declare %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v2f16.v2f16(i32, <2 x half>, <2 x half>) #0 - attributes #0 = { nounwind } !dx.targetTypes = !{!0, !1, !2, !3, !4, !5} @@ -98,7 +70,7 @@ attributes #0 = { nounwind } !3 = !{%dx.types.LinAlgMatrixC8M16N16U2S0 undef, i32 8, i32 16, i32 16, i32 2, i32 0} !4 = !{%dx.types.LinAlgMatrixC4M8N8U2S0 undef, i32 4, i32 8, i32 8, i32 2, i32 0} !5 = !{%dx.types.LinAlgMatrixC21M8N8U2S0 undef, i32 21, i32 8, i32 8, i32 2, i32 0} -!6 = !{!"dxc(private) 1.9.0.5459 (linalg-vali-matrixouterproduct, bd6c0b684-dirty)"} +!6 = !{!"dxc(private) 1.9.0.5461 (linalg-vali-matrixouterproduct, 677283588-dirty)"} !7 = !{i32 1, i32 10} !8 = !{!"cs", i32 6, i32 10} !9 = !{void ()* @main, !"main", null, null, !10} diff --git a/utils/hct/hctdb.py b/utils/hct/hctdb.py index 0d005dfa90..14a78ceaf8 100644 --- a/utils/hct/hctdb.py +++ b/utils/hct/hctdb.py @@ -8729,14 +8729,6 @@ def build_valrules(self): "Instr.LinAlgMatrixMatrixResDimMustMatch", "%0 matrix dimension '%1' must match A.MxB.N '%2'.", ) - self.add_valrule( - "Instr.LinAlgMatrixVectorTypeMustMatch", - "%0 vector element type '%1' must match %2 matrix element type '%3'.", - ) - self.add_valrule( - "Instr.LinAlgMatrixVectorTypeMustMatchPacked", - "%0 vector element type '%1' must be i32 for %2 matrix with non-native element type '%3'." - ) # Some legacy rules: # - space is only supported for shader targets 5.1 and higher From d3dc7439c95e76f5f1ba0800a61f7e63018ca37b Mon Sep 17 00:00:00 2001 From: Ashley Coleman Date: Fri, 21 Aug 2026 11:07:40 -0600 Subject: [PATCH 3/3] address comments --- .../builtins/matrixouterproduct/nominal.hlsl | 12 ++++---- .../LinAlgMatrix/linalgmatrix-outerproduct.ll | 29 ++++++++++++++----- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixouterproduct/nominal.hlsl b/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixouterproduct/nominal.hlsl index 338499fbde..fa4a8530f7 100644 --- a/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixouterproduct/nominal.hlsl +++ b/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixouterproduct/nominal.hlsl @@ -8,37 +8,37 @@ void main() { float4 lhs1 = {1,2,3,4}; float4 rhs1 = {4,3,2,1}; - // Matrix - __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(9, 4, 4, 2, 0)]] mat1; // CHECK: call %dx.types.LinAlgMatrixC9M4N4U2S0 @dx.op.linAlgMatrixOuterProduct.mC9M4N4U2S0.v4f32.v4f32 // CHECK-SAME: (i32 -2147483619, <4 x float> {{.*}}, <4 x float> {{.*}}) ; LinAlgMatrixOuterProduct(vectorA,vectorB) // CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC9M4N4U2S0*, <4 x float>, <4 x float>)" // CHECK2: (i32 417, %dx.types.LinAlgMatrixC9M4N4U2S0* {{.*}}, <4 x float> {{.*}}, <4 x float> {{.*}}) + // Matrix + __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(9, 4, 4, 2, 0)]] mat1; __builtin_LinAlg_MatrixOuterProduct(mat1, lhs1, rhs1); double4 lhs2 = {1,2,3,4}; double4 rhs2 = {4,3,2,1}; - // Matrix - __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(10, 4, 4, 2, 0)]] mat2; // CHECK: call %dx.types.LinAlgMatrixC10M4N4U2S0 @dx.op.linAlgMatrixOuterProduct.mC10M4N4U2S0.v4f64.v4f64 // CHECK-SAME: (i32 -2147483619, <4 x double> {{.*}}, <4 x double> {{.*}}) ; LinAlgMatrixOuterProduct(vectorA,vectorB) // CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC10M4N4U2S0*, <4 x double>, <4 x double>)" // CHECK2: (i32 417, %dx.types.LinAlgMatrixC10M4N4U2S0* {{.*}}, <4 x double> {{.*}}, <4 x double> {{.*}}) + // Matrix + __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(10, 4, 4, 2, 0)]] mat2; __builtin_LinAlg_MatrixOuterProduct(mat2, lhs2, rhs2); vector lhs3 = {1,2,3,4}; vector rhs3 = {4,3,2,1}; - // Matrix - __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(6, 4, 4, 2, 0)]] mat3; // CHECK: call %dx.types.LinAlgMatrixC6M4N4U2S0 @dx.op.linAlgMatrixOuterProduct.mC6M4N4U2S0.v4i64.v4i64 // CHECK-SAME: (i32 -2147483619, <4 x i64> {{.*}}, <4 x i64> {{.*}}) ; LinAlgMatrixOuterProduct(vectorA,vectorB) // CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC6M4N4U2S0*, <4 x i64>, <4 x i64>)" // CHECK2: (i32 417, %dx.types.LinAlgMatrixC6M4N4U2S0* {{.*}}, <4 x i64> {{.*}}, <4 x i64> {{.*}}) + // Matrix + __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(6, 4, 4, 2, 0)]] mat3; __builtin_LinAlg_MatrixOuterProduct(mat3, lhs3, rhs3); } diff --git a/tools/clang/test/LitDXILValidation/LinAlgMatrix/linalgmatrix-outerproduct.ll b/tools/clang/test/LitDXILValidation/LinAlgMatrix/linalgmatrix-outerproduct.ll index 256162be1c..a0b304eb6e 100644 --- a/tools/clang/test/LitDXILValidation/LinAlgMatrix/linalgmatrix-outerproduct.ll +++ b/tools/clang/test/LitDXILValidation/LinAlgMatrix/linalgmatrix-outerproduct.ll @@ -5,10 +5,10 @@ target triple = "dxil-ms-dx" %dx.types.LinAlgMatrixC8M8N8U2S0 = type { i8* } %dx.types.LinAlgMatrixC21M8N8U2S0 = type { i8* } +%dx.types.LinAlgMatrixC8M8N16U2S0 = type { i8* } %dx.types.LinAlgMatrixC8M8N8U2S1 = type { i8* } %dx.types.LinAlgMatrixC8M8N8U1S0 = type { i8* } %dx.types.LinAlgMatrixC8M16N16U2S0 = type { i8* } -%dx.types.LinAlgMatrixC4M8N8U2S0 = type { i8* } define void @main() { ; okay @@ -17,21 +17,28 @@ define void @main() { ; okay %2 = call %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + ; okay + %3 = call %dx.types.LinAlgMatrixC8M8N16U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N16U2S0.v8f16.v16f16(i32 -2147483619, <8 x half> , <16 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + ; CHECK: Function: main: error: Return matrix scope 'Wave' does not match expected scope Thread. ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S1.v8f16.v8f16 - %3 = call %dx.types.LinAlgMatrixC8M8N8U2S1 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S1.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + %4 = call %dx.types.LinAlgMatrixC8M8N8U2S1 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S1.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) ; CHECK-NEXT: Function: main: error: Return matrix use 'B' does not match expected use Accumulator. ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M8N8U1S0.v8f16.v8f16 - %4 = call %dx.types.LinAlgMatrixC8M8N8U1S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U1S0.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + %5 = call %dx.types.LinAlgMatrixC8M8N8U1S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U1S0.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) ; CHECK-NEXT: Function: main: error: Return matrix dimension '16x16' must match derived matrix dimension '8x8'. ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M16N16U2S0.v8f16.v8f16 - %5 = call %dx.types.LinAlgMatrixC8M16N16U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M16N16U2S0.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + %6 = call %dx.types.LinAlgMatrixC8M16N16U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M16N16U2S0.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + + ; CHECK-NEXT: Function: main: error: Return matrix dimension '8x16' must match derived matrix dimension '8x8'. + ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M8N16U2S0.v8f16.v8f16 + %7 = call %dx.types.LinAlgMatrixC8M8N16U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N16U2S0.v8f16.v8f16(i32 -2147483619, <8 x half> , <8 x half> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) ; CHECK-NEXT: Function: main: error: A vector element type 'half' must match B vector element type 'i32' ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8i32 - %6 = call %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8i32(i32 -2147483619, <8 x half> , <8 x i32> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) + %8 = call %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8i32(i32 -2147483619, <8 x half> , <8 x i32> ) ; LinAlgMatrixOuterProduct(vectorA,vectorB) ; CHECK-NEXT: Validation failed. ret void @@ -43,6 +50,9 @@ declare %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8 ; Function Attrs: nounwind declare %dx.types.LinAlgMatrixC21M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC21M8N8U2S0.v8f16.v8f16(i32, <8 x half>, <8 x half>) #0 +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC8M8N16U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N16U2S0.v8f16.v16f16(i32, <8 x half>, <16 x half>) #0 + ; Function Attrs: nounwind declare %dx.types.LinAlgMatrixC8M8N8U2S1 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S1.v8f16.v8f16(i32, <8 x half>, <8 x half>) #0 @@ -52,6 +62,9 @@ declare %dx.types.LinAlgMatrixC8M8N8U1S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8 ; Function Attrs: nounwind declare %dx.types.LinAlgMatrixC8M16N16U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M16N16U2S0.v8f16.v8f16(i32, <8 x half>, <8 x half>) #0 +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC8M8N16U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N16U2S0.v8f16.v8f16(i32, <8 x half>, <8 x half>) #0 + ; Function Attrs: nounwind declare %dx.types.LinAlgMatrixC8M8N8U2S0 @dx.op.linAlgMatrixOuterProduct.mC8M8N8U2S0.v8f16.v8i32(i32, <8 x half>, <8 x i32>) #0 @@ -68,9 +81,9 @@ attributes #0 = { nounwind } !1 = !{%dx.types.LinAlgMatrixC8M8N8U2S1 undef, i32 8, i32 8, i32 8, i32 2, i32 1} !2 = !{%dx.types.LinAlgMatrixC8M8N8U1S0 undef, i32 8, i32 8, i32 8, i32 1, i32 0} !3 = !{%dx.types.LinAlgMatrixC8M16N16U2S0 undef, i32 8, i32 16, i32 16, i32 2, i32 0} -!4 = !{%dx.types.LinAlgMatrixC4M8N8U2S0 undef, i32 4, i32 8, i32 8, i32 2, i32 0} -!5 = !{%dx.types.LinAlgMatrixC21M8N8U2S0 undef, i32 21, i32 8, i32 8, i32 2, i32 0} -!6 = !{!"dxc(private) 1.9.0.5461 (linalg-vali-matrixouterproduct, 677283588-dirty)"} +!4 = !{%dx.types.LinAlgMatrixC21M8N8U2S0 undef, i32 21, i32 8, i32 8, i32 2, i32 0} +!5 = !{%dx.types.LinAlgMatrixC8M8N16U2S0 undef, i32 8, i32 8, i32 16, i32 2, i32 0} +!6 = !{!"dxc(private) 1.9.0.5463 (linalg-vali-convert, c401f722f)"} !7 = !{i32 1, i32 10} !8 = !{!"cs", i32 6, i32 10} !9 = !{void ()* @main, !"main", null, null, !10}