Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions lib/DxilValidation/DxilValidation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1599,6 +1599,67 @@ static void ValidateLinAlgMatrixLoadFromMemory(CallInst *CI,
ValidationContext &ValCtx) {
ValidateLinAlgOpReturnMatrix(CI, ValCtx);
ValidateLinAlgOpParameters(CI, ValCtx);
DxilInst_LinAlgMatrixLoadFromMemory Op(CI);
Comment thread
V-FEXrt marked this conversation as resolved.

std::optional<LinAlgTargetType> RetMat =
GetCheckedLATT(CI->getType(), ValCtx);
if (!RetMat)
return;

// Scope must be wave/threadgroup
if (RetMat->Scope != DXIL::MatrixScope::Wave &&
RetMat->Scope != DXIL::MatrixScope::ThreadGroup)
ValCtx.EmitInstrFormatError(
CI, ValidationRule::InstrLinAlgMatrixScopeMismatch2,
{"Return", MatrixScopeToString(RetMat->Scope), "Wave", "ThreadGroup"});

GEPOperator *GSGEP = cast<GEPOperator>(Op.get_memory());
GlobalVariable *GSMem = cast<GlobalVariable>(GSGEP->getPointerOperand());
Comment thread
V-FEXrt marked this conversation as resolved.
Type *GSMemInnerTy = GSMem->getType();
unsigned GSScalarCount = 1;
if (PointerType *GSMemPtrTy = dyn_cast<PointerType>(GSMemInnerTy))
GSMemInnerTy = GSMemPtrTy->getPointerElementType();
if (ArrayType *GSMemArrTy = dyn_cast<ArrayType>(GSMemInnerTy)) {
GSMemInnerTy = GSMemArrTy->getArrayElementType();
GSScalarCount *= GSMemArrTy->getNumElements();
}
if (VectorType *GSMemVecTy = dyn_cast<VectorType>(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(RetMat->Type, GSMemInnerTy))
ValCtx.EmitInstrFormatError(
CI, ValidationRule::InstrLinAlgMatrixGSMemTypeMustMatch,
{TypeToString(GSMemInnerTy), "return matrix",
ComponentTypeToString(RetMat->Type)});

// gs memory must be large enough for the read
unsigned ElementsPerScalar = ComponentTypeElementsPerScalar(RetMat->Type);
unsigned ExpectedScalarCount =
(RetMat->N + ElementsPerScalar - 1) / ElementsPerScalar * RetMat->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<ConstantInt>(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<ConstantInt>(Op.get_stride())) {
unsigned Stride = StrideV->getLimitedValue();
if (Stride % 16 != 0)
ValCtx.EmitInstrFormatError(CI, ValidationRule::InstrParamMultiple,
{"Stride", "16", std::to_string(Stride)});
}
}

static void ValidateLinAlgMatrixSetElement(CallInst *CI,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ groupshared float SharedArr[64];
void main() {
// CHECK-LABEL: define void @main()

// CHECK: call %dx.types.LinAlgMatrixC4M5N4U1S2 @dx.op.linAlgMatrixLoadFromMemory.mC4M5N4U1S2.f32
// CHECK: call %dx.types.LinAlgMatrixC9M5N4U1S2 @dx.op.linAlgMatrixLoadFromMemory.mC9M5N4U1S2.f32
// CHECK-SAME; (i32 -2147483633, float addrspace(3)* getelementptr inbounds ([64 x float],
// CHECK-SAME: [64 x float] addrspace(3)* @"\01?SharedArr@@3PAMA", i32 0, i32 0), i32 1, i32 2, i32 3)
// CHECK-SAME: [64 x float] addrspace(3)* @"\01?SharedArr@@3PAMA", i32 0, i32 0), i32 128, i32 16, i32 3)
// CHECK-SAME: ; LinAlgMatrixLoadFromMemory(memory,offset,stride,layout)

// CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC4M5N4U1S2*, [64 x float] addrspace(3)*,
// CHECK2-SAME: i32, i32, i32)"(i32 407, %dx.types.LinAlgMatrixC4M5N4U1S2* %mat, [64 x float] addrspace(3)*
// CHECK2-SAME: @"\01?SharedArr@@3PAMA", i32 1, i32 2, i32 3)
__builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(4, 5, 4, 1, 2)]] mat;
__builtin_LinAlg_MatrixLoadFromMemory(mat, SharedArr, 1, 2, 3);
// CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC9M5N4U1S2*, [64 x float] addrspace(3)*,
// CHECK2-SAME: i32, i32, i32)"(i32 407, %dx.types.LinAlgMatrixC9M5N4U1S2* %mat, [64 x float] addrspace(3)*
// CHECK2-SAME: @"\01?SharedArr@@3PAMA", i32 128, i32 16, i32 3)
__builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(9, 5, 4, 1, 2)]] mat;
__builtin_LinAlg_MatrixLoadFromMemory(mat, SharedArr, 128, 16, 3);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,30 @@ groupshared float4 SharedArr[64];

// The array may also reach the builtin through a function parameter.
void LoadIndirect(groupshared float4 Arr[64]) {
__builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(4, 5, 4, 1, 2)]] mat;
__builtin_LinAlg_MatrixLoadFromMemory(mat, Arr, 4, 5, 6);
__builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(9, 5, 4, 1, 2)]] mat;
__builtin_LinAlg_MatrixLoadFromMemory(mat, Arr, 128, 16, 3);
}

[numthreads(4,1,1)]
void main() {
// CHECK-LABEL: define void @main()

// CHECK: call %dx.types.LinAlgMatrixC4M5N4U1S2 @dx.op.linAlgMatrixLoadFromMemory.mC4M5N4U1S2.v4f32
// CHECK: call %dx.types.LinAlgMatrixC9M5N4U1S2 @dx.op.linAlgMatrixLoadFromMemory.mC9M5N4U1S2.v4f32
// CHECK-SAME: (i32 -2147483633, <4 x float> addrspace(3)* getelementptr inbounds ([64 x <4 x float>],
// CHECK-SAME: [64 x <4 x float>] addrspace(3)* @"\01?SharedArr@@3PAV?$vector@M$03@@A", i32 0, i32 0),
// CHECK-SAME: i32 1, i32 2, i32 3)
// CHECK-SAME: i32 128, i32 16, i32 3)
// CHECK-SAME: ; LinAlgMatrixLoadFromMemory(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 407, %dx.types.LinAlgMatrixC4M5N4U1S2* %mat, [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;
__builtin_LinAlg_MatrixLoadFromMemory(mat, SharedArr, 1, 2, 3);
// CHECK2: call void @"dx.hl.op..void (i32, %dx.types.LinAlgMatrixC9M5N4U1S2*, [64 x <4 x float>] addrspace(3)*,
// CHECK2-SAME: i32, i32, i32)"(i32 407, %dx.types.LinAlgMatrixC9M5N4U1S2* %mat, [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_MatrixLoadFromMemory(mat, SharedArr, 128, 16, 3);

// CHECK: call %dx.types.LinAlgMatrixC4M5N4U1S2 @dx.op.linAlgMatrixLoadFromMemory.mC4M5N4U1S2.v4f32
// CHECK: call %dx.types.LinAlgMatrixC9M5N4U1S2 @dx.op.linAlgMatrixLoadFromMemory.mC9M5N4U1S2.v4f32
// CHECK-SAME: (i32 -2147483633, <4 x float> addrspace(3)* getelementptr inbounds ([64 x <4 x float>],
// CHECK-SAME: [64 x <4 x float>] addrspace(3)* @"\01?SharedArr@@3PAV?$vector@M$03@@A", i32 0, i32 0),
// CHECK-SAME: i32 4, i32 5, i32 6)
// CHECK-SAME: i32 128, i32 16, i32 3)
// CHECK-SAME: ; LinAlgMatrixLoadFromMemory(memory,offset,stride,layout)
LoadIndirect(SharedArr);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
; 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.LinAlgMatrixC9M4N4U0S1 = type { i8* }
%dx.types.LinAlgMatrixC9M4N4U0S0 = type { i8* }
%dx.types.LinAlgMatrixC6M4N4U0S2 = type { i8* }
%dx.types.LinAlgMatrixC9M8N8U0S1 = type { i8* }
%dx.types.LinAlgMatrixC9M9N8U0S1 = type { i8* }
%dx.types.LinAlgMatrixC9M8N9U0S1 = type { i8* }

@"\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() {
; okay
%1 = call %dx.types.LinAlgMatrixC9M4N4U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M4N4U0S1.f32(i32 -2147483633, 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) ; LinAlgMatrixLoadFromMemory(memory,offset,stride,layout)

; CHECK: Function: main: error: parameter 'Offset' must be a multiple of 128, got 129
; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixLoadFromMemory.mC9M4N4U0S1.f32
%2 = call %dx.types.LinAlgMatrixC9M4N4U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M4N4U0S1.f32(i32 -2147483633, 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) ; LinAlgMatrixLoadFromMemory(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.linAlgMatrixLoadFromMemory.mC9M4N4U0S1.f32
%3 = call %dx.types.LinAlgMatrixC9M4N4U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M4N4U0S1.f32(i32 -2147483633, 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) ; LinAlgMatrixLoadFromMemory(memory,offset,stride,layout)

; CHECK-NEXT: Function: main: error: Return matrix scope 'Thread' does not match expected scope Wave or ThreadGroup.
; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixLoadFromMemory.mC9M4N4U0S0.f32
%4 = call %dx.types.LinAlgMatrixC9M4N4U0S0 @dx.op.linAlgMatrixLoadFromMemory.mC9M4N4U0S0.f32(i32 -2147483633, 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) ; LinAlgMatrixLoadFromMemory(memory,offset,stride,layout)

; CHECK-NEXT: Function: main: error: Groupshared memory inner type 'float' must match return matrix type 'I64'.
; CHECK-NEXT: note: at {{.*}} @dx.op.linAlgMatrixLoadFromMemory.mC6M4N4U0S2.f32
%5 = call %dx.types.LinAlgMatrixC6M4N4U0S2 @dx.op.linAlgMatrixLoadFromMemory.mC6M4N4U0S2.f32(i32 -2147483633, 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) ; LinAlgMatrixLoadFromMemory(memory,offset,stride,layout)

; okay
%6 = call %dx.types.LinAlgMatrixC9M8N8U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M8N8U0S1.f32(i32 -2147483633, 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) ; LinAlgMatrixLoadFromMemory(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.linAlgMatrixLoadFromMemory.mC9M9N8U0S1.f32
%7 = call %dx.types.LinAlgMatrixC9M9N8U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M9N8U0S1.f32(i32 -2147483633, 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) ; LinAlgMatrixLoadFromMemory(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.linAlgMatrixLoadFromMemory.mC9M8N9U0S1.f32
%8 = call %dx.types.LinAlgMatrixC9M8N9U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M8N9U0S1.f32(i32 -2147483633, 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) ; LinAlgMatrixLoadFromMemory(memory,offset,stride,layout)

; okay
%9 = call %dx.types.LinAlgMatrixC9M8N8U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M8N8U0S1.v4f32(i32 -2147483633, <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) ; LinAlgMatrixLoadFromMemory(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.linAlgMatrixLoadFromMemory.mC9M9N8U0S1.v4f32
%10 = call %dx.types.LinAlgMatrixC9M9N8U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M9N8U0S1.v4f32(i32 -2147483633, <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) ; LinAlgMatrixLoadFromMemory(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.linAlgMatrixLoadFromMemory.mC9M8N9U0S1.v4f32
%11 = call %dx.types.LinAlgMatrixC9M8N9U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M8N9U0S1.v4f32(i32 -2147483633, <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) ; LinAlgMatrixLoadFromMemory(memory,offset,stride,layout)

; CHECK-NEXT: Validation failed.
ret void
}

; Function Attrs: nounwind
declare %dx.types.LinAlgMatrixC9M4N4U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M4N4U0S1.f32(i32, float addrspace(3)*, i32, i32, i32) #0

; Function Attrs: nounwind
declare %dx.types.LinAlgMatrixC9M4N4U0S0 @dx.op.linAlgMatrixLoadFromMemory.mC9M4N4U0S0.f32(i32, float addrspace(3)*, i32, i32, i32) #0

; Function Attrs: nounwind
declare %dx.types.LinAlgMatrixC6M4N4U0S2 @dx.op.linAlgMatrixLoadFromMemory.mC6M4N4U0S2.f32(i32, float addrspace(3)*, i32, i32, i32) #0

; Function Attrs: nounwind
declare %dx.types.LinAlgMatrixC9M8N8U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M8N8U0S1.f32(i32, float addrspace(3)*, i32, i32, i32) #0

; Function Attrs: nounwind
declare %dx.types.LinAlgMatrixC9M9N8U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M9N8U0S1.f32(i32, float addrspace(3)*, i32, i32, i32) #0

; Function Attrs: nounwind
declare %dx.types.LinAlgMatrixC9M8N9U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M8N9U0S1.f32(i32, float addrspace(3)*, i32, i32, i32) #0

; Function Attrs: nounwind
declare %dx.types.LinAlgMatrixC9M8N8U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M8N8U0S1.v4f32(i32, <4 x float> addrspace(3)*, i32, i32, i32) #0

; Function Attrs: nounwind
declare %dx.types.LinAlgMatrixC9M9N8U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M9N8U0S1.v4f32(i32, <4 x float> addrspace(3)*, i32, i32, i32) #0

; Function Attrs: nounwind
declare %dx.types.LinAlgMatrixC9M8N9U0S1 @dx.op.linAlgMatrixLoadFromMemory.mC9M8N9U0S1.v4f32(i32, <4 x float> addrspace(3)*, i32, i32, i32) #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.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.5467 (linalg-vali-matrixaccumulatetomemory, 37b85f973-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}

Loading