diff --git a/docs/DXIL.rst b/docs/DXIL.rst index 74acdd51fa..a590e530a9 100644 --- a/docs/DXIL.rst +++ b/docs/DXIL.rst @@ -3214,6 +3214,8 @@ INSTR.LINALGILLEGALKDIM %0 matrix K dimension out INSTR.LINALGMATRIX2PARTSMUSTMATCH %0 matrix %1 '%2' must match %3 matrix %4 '%5'. INSTR.LINALGMATRIXDIMKVECKMISMATCH %0 vector size '%1' must be %2 for input matrix with K '%3' and Type '%4' INSTR.LINALGMATRIXDIMVECTORMISMATCH %0 vector size '%1' must match input matrix M dimension '%2' +INSTR.LINALGMATRIXGSMEMMUSTBELARGEENOUGH Groupshared memory holds '%0' scalars but must hold at least '%1' scalars. +INSTR.LINALGMATRIXGSMEMTYPEMUSTMATCH Groupshared memory inner type '%0' must match %1 matrix type '%2'. INSTR.LINALGMATRIXLAYOUTREQSTRIDE %0 with layout '%1' requires stride 0. INSTR.LINALGMATRIXLOADTHREADREQUIRESBAB Loading matrix with Thread scope requires ByteAddressBuffer. INSTR.LINALGMATRIXMATRIXKDIMMUSTMATCH K dim of A matrix '%0' must match K dim of B matrix '%1'. %2 != %3. diff --git a/lib/DxilValidation/DxilValidation.cpp b/lib/DxilValidation/DxilValidation.cpp index ca6cefb673..a0aa740797 100644 --- a/lib/DxilValidation/DxilValidation.cpp +++ b/lib/DxilValidation/DxilValidation.cpp @@ -52,6 +52,7 @@ #include #include #include +#include #include using namespace llvm; @@ -1225,6 +1226,66 @@ static void ValidateLinAlgMatrixStoreToDescriptor(CallInst *CI, static void ValidateLinAlgMatrixStoreToMemory(CallInst *CI, ValidationContext &ValCtx) { ValidateLinAlgOpParameters(CI, ValCtx); + DxilInst_LinAlgMatrixStoreToMemory Op(CI); + std::optional Mat = + GetCheckedLATT(Op.get_matrix()->getType(), ValCtx); + if (!Mat) + return; + + // Scope must be wave/threadgroup + if (Mat->Scope != DXIL::MatrixScope::Wave && + Mat->Scope != DXIL::MatrixScope::ThreadGroup) + ValCtx.EmitInstrFormatError( + CI, ValidationRule::InstrLinAlgMatrixScopeMismatch2, + {"Input", MatrixScopeToString(Mat->Scope), "Wave", "ThreadGroup"}); + + GEPOperator *GSGEP = cast(Op.get_memory()); + GlobalVariable *GSMem = cast(GSGEP->getPointerOperand()); + Type *GSMemInnerTy = GSMem->getType(); + unsigned GSScalarCount = 1; + if (PointerType *GSMemPtrTy = dyn_cast(GSMemInnerTy)) + GSMemInnerTy = GSMemPtrTy->getPointerElementType(); + if (ArrayType *GSMemArrTy = dyn_cast(GSMemInnerTy)) { + GSMemInnerTy = GSMemArrTy->getArrayElementType(); + GSScalarCount *= GSMemArrTy->getNumElements(); + } + if (VectorType *GSMemVecTy = dyn_cast(GSMemInnerTy)) { + GSMemInnerTy = GSMemVecTy->getVectorElementType(); + GSScalarCount *= GSMemVecTy->getNumElements(); + } + + // if gs memory inner type != i32 then matrix elem type must match it + if (!GSMemInnerTy->isIntegerTy(32) && + !IsComponentTypeSameNativeType(Mat->Type, GSMemInnerTy)) + ValCtx.EmitInstrFormatError( + CI, ValidationRule::InstrLinAlgMatrixGSMemTypeMustMatch, + {TypeToString(GSMemInnerTy), "input", + ComponentTypeToString(Mat->Type)}); + + // gs memory must be large enough for the write + unsigned ElementsPerScalar = ComponentTypeElementsPerScalar(Mat->Type); + unsigned ExpectedScalarCount = + (Mat->N + ElementsPerScalar - 1) / ElementsPerScalar * Mat->M; + if (ExpectedScalarCount > GSScalarCount) + ValCtx.EmitInstrFormatError( + CI, ValidationRule::InstrLinAlgMatrixGSMemMustBeLargeEnough, + {std::to_string(GSScalarCount), std::to_string(ExpectedScalarCount)}); + + // if it is constant then offset must be 128-byte aligned + if (ConstantInt *OffsetV = dyn_cast(Op.get_offset())) { + unsigned Offset = OffsetV->getLimitedValue(); + if (Offset % 128 != 0) + ValCtx.EmitInstrFormatError(CI, ValidationRule::InstrParamMultiple, + {"Offset", "128", std::to_string(Offset)}); + } + + // if it is constant then stride must be 16-byte aligned + if (ConstantInt *StrideV = dyn_cast(Op.get_stride())) { + unsigned Stride = StrideV->getLimitedValue(); + if (Stride % 16 != 0) + ValCtx.EmitInstrFormatError(CI, ValidationRule::InstrParamMultiple, + {"Stride", "16", std::to_string(Stride)}); + } } static void ValidateLinAlgMatVecMul(CallInst *CI, ValidationContext &ValCtx, diff --git a/lib/DxilValidation/DxilValidationUtils.cpp b/lib/DxilValidation/DxilValidationUtils.cpp index 73f52c763c..0bc191eb1b 100644 --- a/lib/DxilValidation/DxilValidationUtils.cpp +++ b/lib/DxilValidation/DxilValidationUtils.cpp @@ -724,4 +724,27 @@ 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 represented in a native type + default: + return false; + } +} + } // namespace hlsl diff --git a/lib/DxilValidation/DxilValidationUtils.h b/lib/DxilValidation/DxilValidationUtils.h index b9c09d7bff..1dc322e181 100644 --- a/lib/DxilValidation/DxilValidationUtils.h +++ b/lib/DxilValidation/DxilValidationUtils.h @@ -165,4 +165,6 @@ 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); } // namespace hlsl diff --git a/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixstoretomemory/nominal.hlsl b/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixstoretomemory/nominal.hlsl index 51b30ec0c2..aecf41edde 100644 --- a/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixstoretomemory/nominal.hlsl +++ b/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixstoretomemory/nominal.hlsl @@ -9,15 +9,15 @@ groupshared float SharedArr[64]; void main() { // CHECK-LABEL: define void @main() - // CHECK: call void @dx.op.linAlgMatrixStoreToMemory.mC4M5N4U1S2.f32(i32 -2147483627, - // CHECK-SAME: %dx.types.LinAlgMatrixC4M5N4U1S2 %{{.*}}, float addrspace(3)* getelementptr + // CHECK: call void @dx.op.linAlgMatrixStoreToMemory.mC9M5N4U1S2.f32(i32 -2147483627, + // CHECK-SAME: %dx.types.LinAlgMatrixC9M5N4U1S2 %{{.*}}, float addrspace(3)* getelementptr // CHECK-SAME: inbounds ([64 x float], [64 x float] addrspace(3)* @"\01?SharedArr@@3PAMA", - // CHECK-SAME: i32 0, i32 0), i32 1, i32 2, i32 3) ; LinAlgMatrixStoreToMemory(matrix,memory,offset,stride,layout) + // CHECK-SAME: i32 0, i32 0), i32 896, i32 48, i32 3) ; LinAlgMatrixStoreToMemory(matrix,memory,offset,stride,layout) - // CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC4M5N4U1S2, [64 x float] addrspace(3)*, i32, i32, i32)" - // CHECK2-SAME: (i32 410, %dx.types.LinAlgMatrixC4M5N4U1S2 %{{.*}}, [64 x float] addrspace(3)* @"\01?SharedArr@@3PAMA", - // CHECK2-SAME: i32 1, i32 2, i32 3) - __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(4, 5, 4, 1, 2)]] mat; + // CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC9M5N4U1S2, [64 x float] addrspace(3)*, i32, i32, i32)" + // CHECK2-SAME: (i32 410, %dx.types.LinAlgMatrixC9M5N4U1S2 %{{.*}}, [64 x float] addrspace(3)* @"\01?SharedArr@@3PAMA", + // CHECK2-SAME: i32 896, i32 48, i32 3) + __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(9, 5, 4, 1, 2)]] mat; __builtin_LinAlg_FillMatrix(mat, 1); - __builtin_LinAlg_MatrixStoreToMemory(mat, SharedArr, 1, 2, 3); + __builtin_LinAlg_MatrixStoreToMemory(mat, SharedArr, 128 * 7, 16 * 3, 3); } diff --git a/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixstoretomemory/vector-array.hlsl b/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixstoretomemory/vector-array.hlsl index 83ccf72c5e..71017a21c0 100644 --- a/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixstoretomemory/vector-array.hlsl +++ b/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/matrixstoretomemory/vector-array.hlsl @@ -13,16 +13,16 @@ groupshared float4 SharedArr[64]; void main() { // CHECK-LABEL: define void @main() - // CHECK: call void @dx.op.linAlgMatrixStoreToMemory.mC4M5N4U1S2.v4f32(i32 -2147483627, - // CHECK-SAME: %dx.types.LinAlgMatrixC4M5N4U1S2 %{{.*}}, <4 x float> addrspace(3)* getelementptr + // CHECK: call void @dx.op.linAlgMatrixStoreToMemory.mC9M5N4U1S2.v4f32(i32 -2147483627, + // CHECK-SAME: %dx.types.LinAlgMatrixC9M5N4U1S2 %{{.*}}, <4 x float> addrspace(3)* getelementptr // CHECK-SAME: inbounds ([64 x <4 x float>], [64 x <4 x float>] addrspace(3)* - // CHECK-SAME: @"\01?SharedArr@@3PAV?$vector@M$03@@A", i32 0, i32 0), i32 1, i32 2, i32 3) + // CHECK-SAME: @"\01?SharedArr@@3PAV?$vector@M$03@@A", i32 0, i32 0), i32 128, i32 16, i32 3) // CHECK-SAME: ; LinAlgMatrixStoreToMemory(matrix,memory,offset,stride,layout) - // CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC4M5N4U1S2, [64 x <4 x float>] addrspace(3)*, - // CHECK2-SAME: i32, i32, i32)"(i32 410, %dx.types.LinAlgMatrixC4M5N4U1S2 %{{.*}}, [64 x <4 x float>] addrspace(3)* - // CHECK2-SAME: @"\01?SharedArr@@3PAV?$vector@M$03@@A", i32 1, i32 2, i32 3) - __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(4, 5, 4, 1, 2)]] mat; + // CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC9M5N4U1S2, [64 x <4 x float>] addrspace(3)*, + // CHECK2-SAME: i32, i32, i32)"(i32 410, %dx.types.LinAlgMatrixC9M5N4U1S2 %{{.*}}, [64 x <4 x float>] addrspace(3)* + // CHECK2-SAME: @"\01?SharedArr@@3PAV?$vector@M$03@@A", i32 128, i32 16, i32 3) + __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(9, 5, 4, 1, 2)]] mat; __builtin_LinAlg_FillMatrix(mat, 1); - __builtin_LinAlg_MatrixStoreToMemory(mat, SharedArr, 1, 2, 3); + __builtin_LinAlg_MatrixStoreToMemory(mat, SharedArr, 128, 16, 3); } diff --git a/tools/clang/test/LitDXILValidation/LinAlgMatrix/linalgmatrix-matrixstoretomemory.ll b/tools/clang/test/LitDXILValidation/LinAlgMatrix/linalgmatrix-matrixstoretomemory.ll new file mode 100644 index 0000000000..bdad7d1b08 --- /dev/null +++ b/tools/clang/test/LitDXILValidation/LinAlgMatrix/linalgmatrix-matrixstoretomemory.ll @@ -0,0 +1,158 @@ +; 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.Handle = type { i8* } +%dx.types.ResBind = type { i32, i32, i32, i8 } +%dx.types.ResourceProperties = type { i32, i32 } +%dx.types.LinAlgMatrixC9M4N4U0S0 = type { i8* } +%dx.types.LinAlgMatrixC9M4N4U0S1 = type { i8* } +%dx.types.LinAlgMatrixC6M4N4U0S2 = type { i8* } +%dx.types.LinAlgMatrixC9M8N8U0S1 = type { i8* } +%dx.types.LinAlgMatrixC9M9N8U0S1 = type { i8* } +%dx.types.LinAlgMatrixC9M8N9U0S1 = type { i8* } +%struct.ByteAddressBuffer = type { i32 } + +@"\01?SharedArr@@3PAMA" = external addrspace(3) global [64 x float], align 4 +@"\01?SharedVecArr@@3PAV?$vector@M$03@@A" = external addrspace(3) global [16 x <4 x float>], align 4 + +define void @main() { + %1 = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217, %dx.types.ResBind zeroinitializer, i32 0, i1 false) ; CreateHandleFromBinding(bind,index,nonUniformIndex) + %2 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %1, %dx.types.ResourceProperties { i32 11, i32 0 }) ; AnnotateHandle(res,props) resource: ByteAddressBuffer + %3 = call %dx.types.LinAlgMatrixC9M4N4U0S0 @dx.op.linAlgMatrixLoadFromDescriptor.mC9M4N4U0S0(i32 -2147483634, %dx.types.Handle %2, i32 0, i32 0, i32 0, i32 128) ; LinAlgMatrixLoadFromDescriptor(handle,offset,stride,layout,align) + %4 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %1, %dx.types.ResourceProperties { i32 11, i32 0 }) ; AnnotateHandle(res,props) resource: ByteAddressBuffer + %5 = call %dx.types.LinAlgMatrixC9M4N4U0S1 @dx.op.linAlgMatrixLoadFromDescriptor.mC9M4N4U0S1(i32 -2147483634, %dx.types.Handle %4, i32 0, i32 0, i32 0, i32 128) ; LinAlgMatrixLoadFromDescriptor(handle,offset,stride,layout,align) + %6 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %1, %dx.types.ResourceProperties { i32 11, i32 0 }) ; AnnotateHandle(res,props) resource: ByteAddressBuffer + %7 = call %dx.types.LinAlgMatrixC6M4N4U0S2 @dx.op.linAlgMatrixLoadFromDescriptor.mC6M4N4U0S2(i32 -2147483634, %dx.types.Handle %6, i32 0, i32 0, i32 0, i32 128) ; LinAlgMatrixLoadFromDescriptor(handle,offset,stride,layout,align) + %8 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %1, %dx.types.ResourceProperties { i32 11, i32 0 }) ; AnnotateHandle(res,props) resource: ByteAddressBuffer + %9 = call %dx.types.LinAlgMatrixC9M8N8U0S1 @dx.op.linAlgMatrixLoadFromDescriptor.mC9M8N8U0S1(i32 -2147483634, %dx.types.Handle %8, i32 0, i32 0, i32 0, i32 128) ; LinAlgMatrixLoadFromDescriptor(handle,offset,stride,layout,align) + %10 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %1, %dx.types.ResourceProperties { i32 11, i32 0 }) ; AnnotateHandle(res,props) resource: ByteAddressBuffer + %11 = call %dx.types.LinAlgMatrixC9M9N8U0S1 @dx.op.linAlgMatrixLoadFromDescriptor.mC9M9N8U0S1(i32 -2147483634, %dx.types.Handle %10, i32 0, i32 0, i32 0, i32 128) ; LinAlgMatrixLoadFromDescriptor(handle,offset,stride,layout,align) + %12 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %1, %dx.types.ResourceProperties { i32 11, i32 0 }) ; AnnotateHandle(res,props) resource: ByteAddressBuffer + %13 = call %dx.types.LinAlgMatrixC9M8N9U0S1 @dx.op.linAlgMatrixLoadFromDescriptor.mC9M8N9U0S1(i32 -2147483634, %dx.types.Handle %12, i32 0, i32 0, i32 0, i32 128) ; LinAlgMatrixLoadFromDescriptor(handle,offset,stride,layout,align) + + ; okay + call void @dx.op.linAlgMatrixStoreToMemory.mC9M4N4U0S1.f32(i32 -2147483627, %dx.types.LinAlgMatrixC9M4N4U0S1 %5, float addrspace(3)* getelementptr inbounds ([64 x float], [64 x float] addrspace(3)* @"\01?SharedArr@@3PAMA", i32 0, i32 0), i32 128, i32 16, i32 0) ; LinAlgMatrixStoreToMemory(matrix,memory,offset,stride,layout) + + ; CHECK: Function: main: error: parameter 'Offset' must be a multiple of 128, got 129 + ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixStoreToMemory.mC9M4N4U0S1.f32 + call void @dx.op.linAlgMatrixStoreToMemory.mC9M4N4U0S1.f32(i32 -2147483627, %dx.types.LinAlgMatrixC9M4N4U0S1 %5, float addrspace(3)* getelementptr inbounds ([64 x float], [64 x float] addrspace(3)* @"\01?SharedArr@@3PAMA", i32 0, i32 0), i32 129, i32 16, i32 0) ; LinAlgMatrixStoreToMemory(matrix,memory,offset,stride,layout) + + ; CHECK-NEXT: Function: main: error: parameter 'Stride' must be a multiple of 16, got 17 + ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixStoreToMemory.mC9M4N4U0S1.f32 + call void @dx.op.linAlgMatrixStoreToMemory.mC9M4N4U0S1.f32(i32 -2147483627, %dx.types.LinAlgMatrixC9M4N4U0S1 %5, float addrspace(3)* getelementptr inbounds ([64 x float], [64 x float] addrspace(3)* @"\01?SharedArr@@3PAMA", i32 0, i32 0), i32 128, i32 17, i32 0) ; LinAlgMatrixStoreToMemory(matrix,memory,offset,stride,layout) + + ; CHECK-NEXT: Function: main: error: Input matrix scope 'Thread' does not match expected scope Wave or ThreadGroup. + ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixStoreToMemory.mC9M4N4U0S0.f32 + call void @dx.op.linAlgMatrixStoreToMemory.mC9M4N4U0S0.f32(i32 -2147483627, %dx.types.LinAlgMatrixC9M4N4U0S0 %3, float addrspace(3)* getelementptr inbounds ([64 x float], [64 x float] addrspace(3)* @"\01?SharedArr@@3PAMA", i32 0, i32 0), i32 128, i32 16, i32 0) ; LinAlgMatrixStoreToMemory(matrix,memory,offset,stride,layout) + + ; CHECK-NEXT: Function: main: error: Groupshared memory inner type 'float' must match input matrix type 'I64'. + ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixStoreToMemory.mC6M4N4U0S2.f32 + call void @dx.op.linAlgMatrixStoreToMemory.mC6M4N4U0S2.f32(i32 -2147483627, %dx.types.LinAlgMatrixC6M4N4U0S2 %7, float addrspace(3)* getelementptr inbounds ([64 x float], [64 x float] addrspace(3)* @"\01?SharedArr@@3PAMA", i32 0, i32 0), i32 128, i32 16, i32 0) ; LinAlgMatrixStoreToMemory(matrix,memory,offset,stride,layout) + + ; okay + call void @dx.op.linAlgMatrixStoreToMemory.mC9M8N8U0S1.f32(i32 -2147483627, %dx.types.LinAlgMatrixC9M8N8U0S1 %9, float addrspace(3)* getelementptr inbounds ([64 x float], [64 x float] addrspace(3)* @"\01?SharedArr@@3PAMA", i32 0, i32 0), i32 128, i32 16, i32 0) ; LinAlgMatrixStoreToMemory(matrix,memory,offset,stride,layout) + + ; CHECK-NEXT: Function: main: error: Groupshared memory holds '64' scalars but must hold at least '72' scalars. + ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixStoreToMemory.mC9M9N8U0S1.f32 + call void @dx.op.linAlgMatrixStoreToMemory.mC9M9N8U0S1.f32(i32 -2147483627, %dx.types.LinAlgMatrixC9M9N8U0S1 %11, float addrspace(3)* getelementptr inbounds ([64 x float], [64 x float] addrspace(3)* @"\01?SharedArr@@3PAMA", i32 0, i32 0), i32 128, i32 16, i32 0) ; LinAlgMatrixStoreToMemory(matrix,memory,offset,stride,layout) + + ; CHECK-NEXT: Function: main: error: Groupshared memory holds '64' scalars but must hold at least '72' scalars. + ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixStoreToMemory.mC9M8N9U0S1.f32 + call void @dx.op.linAlgMatrixStoreToMemory.mC9M8N9U0S1.f32(i32 -2147483627, %dx.types.LinAlgMatrixC9M8N9U0S1 %13, float addrspace(3)* getelementptr inbounds ([64 x float], [64 x float] addrspace(3)* @"\01?SharedArr@@3PAMA", i32 0, i32 0), i32 128, i32 16, i32 0) ; LinAlgMatrixStoreToMemory(matrix,memory,offset,stride,layout) + + ; okay + call void @dx.op.linAlgMatrixStoreToMemory.mC9M8N8U0S1.v4f32(i32 -2147483627, %dx.types.LinAlgMatrixC9M8N8U0S1 %9, <4 x float> addrspace(3)* getelementptr inbounds ([16 x <4 x float>], [16 x <4 x float>] addrspace(3)* @"\01?SharedVecArr@@3PAV?$vector@M$03@@A", i32 0, i32 0), i32 128, i32 16, i32 0) ; LinAlgMatrixStoreToMemory(matrix,memory,offset,stride,layout) + + ; CHECK-NEXT: Function: main: error: Groupshared memory holds '64' scalars but must hold at least '72' scalars. + ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixStoreToMemory.mC9M9N8U0S1.v4f32 + call void @dx.op.linAlgMatrixStoreToMemory.mC9M9N8U0S1.v4f32(i32 -2147483627, %dx.types.LinAlgMatrixC9M9N8U0S1 %11, <4 x float> addrspace(3)* getelementptr inbounds ([16 x <4 x float>], [16 x <4 x float>] addrspace(3)* @"\01?SharedVecArr@@3PAV?$vector@M$03@@A", i32 0, i32 0), i32 128, i32 16, i32 0) ; LinAlgMatrixStoreToMemory(matrix,memory,offset,stride,layout) + + ; CHECK-NEXT: Function: main: error: Groupshared memory holds '64' scalars but must hold at least '72' scalars. + ; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixStoreToMemory.mC9M8N9U0S1.v4f32 + call void @dx.op.linAlgMatrixStoreToMemory.mC9M8N9U0S1.v4f32(i32 -2147483627, %dx.types.LinAlgMatrixC9M8N9U0S1 %13, <4 x float> addrspace(3)* getelementptr inbounds ([16 x <4 x float>], [16 x <4 x float>] addrspace(3)* @"\01?SharedVecArr@@3PAV?$vector@M$03@@A", i32 0, i32 0), i32 128, i32 16, i32 0) ; LinAlgMatrixStoreToMemory(matrix,memory,offset,stride,layout) + + ; CHECK-NEXT: Validation failed. + ret void +} + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC9M4N4U0S0 @dx.op.linAlgMatrixLoadFromDescriptor.mC9M4N4U0S0(i32, %dx.types.Handle, i32, i32, i32, i32) #0 + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC9M4N4U0S1 @dx.op.linAlgMatrixLoadFromDescriptor.mC9M4N4U0S1(i32, %dx.types.Handle, i32, i32, i32, i32) #0 + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC6M4N4U0S2 @dx.op.linAlgMatrixLoadFromDescriptor.mC6M4N4U0S2(i32, %dx.types.Handle, i32, i32, i32, i32) #0 + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC9M8N8U0S1 @dx.op.linAlgMatrixLoadFromDescriptor.mC9M8N8U0S1(i32, %dx.types.Handle, i32, i32, i32, i32) #0 + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC9M9N8U0S1 @dx.op.linAlgMatrixLoadFromDescriptor.mC9M9N8U0S1(i32, %dx.types.Handle, i32, i32, i32, i32) #0 + +; Function Attrs: nounwind +declare %dx.types.LinAlgMatrixC9M8N9U0S1 @dx.op.linAlgMatrixLoadFromDescriptor.mC9M8N9U0S1(i32, %dx.types.Handle, i32, i32, i32, i32) #0 + +; Function Attrs: nounwind +declare void @dx.op.linAlgMatrixStoreToMemory.mC9M4N4U0S1.f32(i32, %dx.types.LinAlgMatrixC9M4N4U0S1, float addrspace(3)*, i32, i32, i32) #0 + +; Function Attrs: nounwind +declare void @dx.op.linAlgMatrixStoreToMemory.mC9M4N4U0S0.f32(i32, %dx.types.LinAlgMatrixC9M4N4U0S0, float addrspace(3)*, i32, i32, i32) #0 + +; Function Attrs: nounwind +declare void @dx.op.linAlgMatrixStoreToMemory.mC6M4N4U0S2.f32(i32, %dx.types.LinAlgMatrixC6M4N4U0S2, float addrspace(3)*, i32, i32, i32) #0 + +; Function Attrs: nounwind +declare void @dx.op.linAlgMatrixStoreToMemory.mC9M8N8U0S1.f32(i32, %dx.types.LinAlgMatrixC9M8N8U0S1, float addrspace(3)*, i32, i32, i32) #0 + +; Function Attrs: nounwind +declare void @dx.op.linAlgMatrixStoreToMemory.mC9M9N8U0S1.f32(i32, %dx.types.LinAlgMatrixC9M9N8U0S1, float addrspace(3)*, i32, i32, i32) #0 + +; Function Attrs: nounwind +declare void @dx.op.linAlgMatrixStoreToMemory.mC9M8N9U0S1.f32(i32, %dx.types.LinAlgMatrixC9M8N9U0S1, float addrspace(3)*, i32, i32, i32) #0 + +; Function Attrs: nounwind +declare void @dx.op.linAlgMatrixStoreToMemory.mC9M8N8U0S1.v4f32(i32, %dx.types.LinAlgMatrixC9M8N8U0S1, <4 x float> addrspace(3)*, i32, i32, i32) #0 + +; Function Attrs: nounwind +declare void @dx.op.linAlgMatrixStoreToMemory.mC9M9N8U0S1.v4f32(i32, %dx.types.LinAlgMatrixC9M9N8U0S1, <4 x float> addrspace(3)*, i32, i32, i32) #0 + +; Function Attrs: nounwind +declare void @dx.op.linAlgMatrixStoreToMemory.mC9M8N9U0S1.v4f32(i32, %dx.types.LinAlgMatrixC9M8N9U0S1, <4 x float> addrspace(3)*, i32, i32, i32) #0 + +; Function Attrs: nounwind readnone +declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #1 + +; Function Attrs: nounwind readnone +declare %dx.types.Handle @dx.op.createHandleFromBinding(i32, %dx.types.ResBind, i32, i1) #1 + +attributes #0 = { nounwind } +attributes #1 = { nounwind readnone } + +!dx.targetTypes = !{!0, !1, !2, !3, !4, !5} +!llvm.ident = !{!6} +!dx.version = !{!7} +!dx.valver = !{!7} +!dx.shaderModel = !{!8} +!dx.resources = !{!9} +!dx.entryPoints = !{!12} + +!0 = !{%dx.types.LinAlgMatrixC9M4N4U0S0 undef, i32 9, i32 4, i32 4, i32 0, i32 0} +!1 = !{%dx.types.LinAlgMatrixC9M4N4U0S1 undef, i32 9, i32 4, i32 4, i32 0, i32 1} +!2 = !{%dx.types.LinAlgMatrixC6M4N4U0S2 undef, i32 6, i32 4, i32 4, i32 0, i32 2} +!3 = !{%dx.types.LinAlgMatrixC9M8N8U0S1 undef, i32 9, i32 8, i32 8, i32 0, i32 1} +!4 = !{%dx.types.LinAlgMatrixC9M9N8U0S1 undef, i32 9, i32 9, i32 8, i32 0, i32 1} +!5 = !{%dx.types.LinAlgMatrixC9M8N9U0S1 undef, i32 9, i32 8, i32 9, i32 0, i32 1} +!6 = !{!"dxc(private) 1.9.0.5466 (linalg-vali-matrixstoretomemory, 07bef449f-dirty)"} +!7 = !{i32 1, i32 10} +!8 = !{!"cs", i32 6, i32 10} +!9 = !{!10, null, null, null} +!10 = !{!11} +!11 = !{i32 0, %struct.ByteAddressBuffer* undef, !"", i32 0, i32 0, i32 1, i32 11, i32 0, null} +!12 = !{void ()* @main, !"main", null, !9, !13} +!13 = !{i32 0, i64 8388624, i32 4, !14} +!14 = !{i32 1, i32 1, i32 1} + diff --git a/utils/hct/hctdb.py b/utils/hct/hctdb.py index 23a10c5d3d..550a66078f 100644 --- a/utils/hct/hctdb.py +++ b/utils/hct/hctdb.py @@ -8729,6 +8729,14 @@ def build_valrules(self): "Instr.LinAlgMatrixMatrixResDimMustMatch", "%0 matrix dimension '%1' must match A.MxB.N '%2'.", ) + self.add_valrule( + "Instr.LinAlgMatrixGSMemTypeMustMatch", + "Groupshared memory inner type '%0' must match %1 matrix type '%2'.", + ) + self.add_valrule( + "Instr.LinAlgMatrixGSMemMustBeLargeEnough", + "Groupshared memory holds '%0' scalars but must hold at least '%1' scalars.", + ) # Some legacy rules: # - space is only supported for shader targets 5.1 and higher