From 2bf2e17248e8725d6b808df470fd2249efae01ef Mon Sep 17 00:00:00 2001 From: Ashley Coleman Date: Tue, 17 Feb 2026 13:23:34 -0700 Subject: [PATCH 1/2] [SM6.10] Implement FillMatrix Builtin Implements the first linalg DXIL op including required support for overload name generation. This also adds lowering placeholders so that subsequent DXIL op implementations may be merged in parallel without risk of merge conflict --- include/dxc/DXIL/DxilUtil.h | 2 + lib/DXIL/DxilOperations.cpp | 4 + lib/DXIL/DxilUtil.cpp | 18 ++ lib/HLSL/HLOperationLower.cpp | 181 +++++++++++++-- .../linalg/builtins/fillmatrix/nominal.hlsl | 14 ++ .../hlsl/linalg/builtins/fillmatrix/ast.hlsl | 15 ++ .../linalg/builtins/fillmatrix/errors.hlsl | 216 ++++++++++++++++++ .../linalg/builtins/fillmatrix/nominal.hlsl | 10 + .../fillmatrix/unavailable_pre_sm610.hlsl | 9 + 9 files changed, 444 insertions(+), 25 deletions(-) create mode 100644 tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/fillmatrix/nominal.hlsl create mode 100644 tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/ast.hlsl create mode 100644 tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/errors.hlsl create mode 100644 tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/nominal.hlsl create mode 100644 tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/unavailable_pre_sm610.hlsl diff --git a/include/dxc/DXIL/DxilUtil.h b/include/dxc/DXIL/DxilUtil.h index ca8f2ac755..82e3a1c16b 100644 --- a/include/dxc/DXIL/DxilUtil.h +++ b/include/dxc/DXIL/DxilUtil.h @@ -164,6 +164,8 @@ bool IsHLSLObjectType(llvm::Type *Ty); bool IsHLSLRayQueryType(llvm::Type *Ty); llvm::Type *GetHLSLHitObjectType(llvm::Module *M); bool IsHLSLHitObjectType(llvm::Type *Ty); +bool IsHLSLLinAlgMatrixType(llvm::Type *Ty); +llvm::StringRef GetHLSLLinAlgMatrixTypeMangling(llvm::StructType *Ty); bool IsHLSLResourceDescType(llvm::Type *Ty); bool IsResourceSingleComponent(llvm::Type *Ty); uint8_t GetResourceComponentCount(llvm::Type *Ty); diff --git a/lib/DXIL/DxilOperations.cpp b/lib/DXIL/DxilOperations.cpp index fa9e0fde4c..07e749cb64 100644 --- a/lib/DXIL/DxilOperations.cpp +++ b/lib/DXIL/DxilOperations.cpp @@ -13,6 +13,7 @@ #include "dxc/DXIL/DxilConstants.h" #include "dxc/DXIL/DxilInstructions.h" #include "dxc/DXIL/DxilModule.h" +#include "dxc/DXIL/DxilUtil.h" #include "dxc/Support/Global.h" #include "llvm/ADT/ArrayRef.h" @@ -3173,6 +3174,9 @@ StringRef OP::GetTypeName(Type *Ty, SmallVectorImpl &Storage) { return ST->getStructName(); } else if (TypeSlot == TS_Object) { StructType *ST = cast(Ty); + if (dxilutil::IsHLSLLinAlgMatrixType(Ty)) + return (Twine("m") + Twine(dxilutil::GetHLSLLinAlgMatrixTypeMangling(ST))) + .toStringRef(Storage); return ST->getStructName(); } else if (TypeSlot == TS_Vector) { VectorType *VecTy = cast(Ty); diff --git a/lib/DXIL/DxilUtil.cpp b/lib/DXIL/DxilUtil.cpp index cc0b509772..082bcf0831 100644 --- a/lib/DXIL/DxilUtil.cpp +++ b/lib/DXIL/DxilUtil.cpp @@ -18,9 +18,11 @@ #include "dxc/Support/Global.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DIBuilder.h" +#include "llvm/IR/DerivedTypes.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/GetElementPtrTypeIterator.h" @@ -577,6 +579,9 @@ bool IsHLSLObjectType(llvm::Type *Ty) { if (IsHLSLHitObjectType(Ty)) return true; + + if (IsHLSLLinAlgMatrixType(Ty)) + return true; } return false; } @@ -612,6 +617,19 @@ bool IsHLSLHitObjectType(llvm::Type *Ty) { return ST->getName() == "dx.types.HitObject"; } +bool IsHLSLLinAlgMatrixType(llvm::Type *Ty) { + llvm::StructType *ST = dyn_cast(Ty); + if (!ST) + return false; + if (!ST->hasName()) + return false; + return ST->getName().startswith("dx.types.LinAlgMatrix"); +} + +StringRef GetHLSLLinAlgMatrixTypeMangling(llvm::StructType *Ty) { + return Ty->getStructName().substr(sizeof("dx.types.LinAlgMatrix") - 1); +} + bool IsHLSLResourceDescType(llvm::Type *Ty) { if (llvm::StructType *ST = dyn_cast(Ty)) { if (!ST->hasName()) diff --git a/lib/HLSL/HLOperationLower.cpp b/lib/HLSL/HLOperationLower.cpp index 2665c441a6..b959f34495 100644 --- a/lib/HLSL/HLOperationLower.cpp +++ b/lib/HLSL/HLOperationLower.cpp @@ -6908,6 +6908,131 @@ Value *TranslateVectorAccumulate(CallInst *CI, IntrinsicOp IOP, {OpArg, InputVector, MatrixBuffer, MatrixOffset}); } +Value *TranslateLinAlgFillMatrix(CallInst *CI, IntrinsicOp IOP, + OP::OpCode OpCode, + HLOperationLowerHelper &Helper, + HLObjectOperationLowerHelper *ObjHelper, + bool &Translated) { + hlsl::OP *HlslOp = &Helper.hlslOP; + IRBuilder<> Builder(CI); + + Value *MatrixPtr = CI->getArgOperand(1); + DXASSERT_NOMSG(isa(MatrixPtr->getType())); + Type *MatrixType = MatrixPtr->getType()->getPointerElementType(); + Value *Scalar = CI->getArgOperand(2); + + Constant *OpArg = HlslOp->GetU32Const((unsigned)OpCode); + Function *DxilFunc = + HlslOp->GetOpFunc(OpCode, {MatrixType, Scalar->getType()}); + + Value *Matrix = Builder.CreateCall(DxilFunc, {OpArg, Scalar}); + Builder.CreateStore(Matrix, MatrixPtr); + + return nullptr; +} + +Value *TranslateLinAlgMatrixAccumStoreToDescriptor( + CallInst *CI, IntrinsicOp IOP, OP::OpCode OpCode, + HLOperationLowerHelper &Helper, HLObjectOperationLowerHelper *ObjHelper, + bool &Translated) { + DXASSERT(false, "Not implemented."); + return nullptr; +} + +Value *TranslateLinAlgMatVecMul(CallInst *CI, IntrinsicOp IOP, + OP::OpCode OpCode, + HLOperationLowerHelper &Helper, + HLObjectOperationLowerHelper *ObjHelper, + bool &Translated) { + DXASSERT(false, "Not implemented."); + return nullptr; +} + +Value *TranslateLinAlgMatVecMulAdd(CallInst *CI, IntrinsicOp IOP, + OP::OpCode OpCode, + HLOperationLowerHelper &Helper, + HLObjectOperationLowerHelper *ObjHelper, + bool &Translated) { + DXASSERT(false, "Not implemented."); + return nullptr; +} + +Value *TranslateLinAlgMatrixLoadFromDescriptor( + CallInst *CI, IntrinsicOp IOP, OP::OpCode OpCode, + HLOperationLowerHelper &Helper, HLObjectOperationLowerHelper *ObjHelper, + bool &Translated) { + DXASSERT(false, "Not implemented."); + return nullptr; +} + +Value *TranslateLinAlgMatrixOuterProduct( + CallInst *CI, IntrinsicOp IOP, OP::OpCode OpCode, + HLOperationLowerHelper &Helper, HLObjectOperationLowerHelper *ObjHelper, + bool &Translated) { + DXASSERT(false, "Not implemented."); + return nullptr; +} + +Value *TranslateLinAlgMatrixAccumulate(CallInst *CI, IntrinsicOp IOP, + OP::OpCode OpCode, + HLOperationLowerHelper &Helper, + HLObjectOperationLowerHelper *ObjHelper, + bool &Translated) { + DXASSERT(false, "Not implemented."); + return nullptr; +} + +Value *TranslateLinAlgMatrixGetCoordinate( + CallInst *CI, IntrinsicOp IOP, OP::OpCode OpCode, + HLOperationLowerHelper &Helper, HLObjectOperationLowerHelper *ObjHelper, + bool &Translated) { + DXASSERT(false, "Not implemented."); + return nullptr; +} + +Value *TranslateLinAlgMatrixGetElement(CallInst *CI, IntrinsicOp IOP, + OP::OpCode OpCode, + HLOperationLowerHelper &Helper, + HLObjectOperationLowerHelper *ObjHelper, + bool &Translated) { + DXASSERT(false, "Not implemented."); + return nullptr; +} + +Value *TranslateLinAlgMatrixSetElement(CallInst *CI, IntrinsicOp IOP, + OP::OpCode OpCode, + HLOperationLowerHelper &Helper, + HLObjectOperationLowerHelper *ObjHelper, + bool &Translated) { + DXASSERT(false, "Not implemented."); + return nullptr; +} + +Value *TranslateLinAlgMatrixMatrixMultiply( + CallInst *CI, IntrinsicOp IOP, OP::OpCode OpCode, + HLOperationLowerHelper &Helper, HLObjectOperationLowerHelper *ObjHelper, + bool &Translated) { + DXASSERT(false, "Not implemented."); + return nullptr; +} + +Value *TranslateLinAlgMatrixMatrixMultiplyAccumulate( + CallInst *CI, IntrinsicOp IOP, OP::OpCode OpCode, + HLOperationLowerHelper &Helper, HLObjectOperationLowerHelper *ObjHelper, + bool &Translated) { + DXASSERT(false, "Not implemented."); + return nullptr; +} + +Value *TranslateLinAlgCopyConvertMatrix(CallInst *CI, IntrinsicOp IOP, + OP::OpCode OpCode, + HLOperationLowerHelper &Helper, + HLObjectOperationLowerHelper *ObjHelper, + bool &Translated) { + DXASSERT(false, "Not implemented."); + return nullptr; +} + } // namespace // Lower table. @@ -7657,44 +7782,50 @@ constexpr IntrinsicLower gLowerTable[] = { TranslateHitObjectTriangleObjectPositions, DXIL::OpCode::HitObject_TriangleObjectPosition}, - {IntrinsicOp::IOP___builtin_LinAlg_CopyConvertMatrix, EmptyLower, - DXIL::OpCode::LinAlgCopyConvertMatrix}, - {IntrinsicOp::IOP___builtin_LinAlg_FillMatrix, EmptyLower, + {IntrinsicOp::IOP___builtin_LinAlg_CopyConvertMatrix, + TranslateLinAlgCopyConvertMatrix, DXIL::OpCode::LinAlgCopyConvertMatrix}, + {IntrinsicOp::IOP___builtin_LinAlg_FillMatrix, TranslateLinAlgFillMatrix, DXIL::OpCode::LinAlgFillMatrix}, - {IntrinsicOp::IOP___builtin_LinAlg_MatrixGetCoordinate, EmptyLower, + {IntrinsicOp::IOP___builtin_LinAlg_MatrixGetCoordinate, + TranslateLinAlgMatrixGetCoordinate, DXIL::OpCode::LinAlgMatrixGetCoordinate}, - {IntrinsicOp::IOP___builtin_LinAlg_MatrixGetElement, EmptyLower, - DXIL::OpCode::LinAlgMatrixGetElement}, - {IntrinsicOp::IOP___builtin_LinAlg_MatrixLength, EmptyLower, + {IntrinsicOp::IOP___builtin_LinAlg_MatrixGetElement, + TranslateLinAlgMatrixGetElement, DXIL::OpCode::LinAlgMatrixGetElement}, + {IntrinsicOp::IOP___builtin_LinAlg_MatrixLength, TrivialUnaryOperation, DXIL::OpCode::LinAlgMatrixLength}, - {IntrinsicOp::IOP___builtin_LinAlg_MatrixLoadFromDescriptor, EmptyLower, + {IntrinsicOp::IOP___builtin_LinAlg_MatrixLoadFromDescriptor, + TranslateLinAlgMatrixLoadFromDescriptor, DXIL::OpCode::LinAlgMatrixLoadFromDescriptor}, {IntrinsicOp::IOP___builtin_LinAlg_MatrixLoadFromMemory, EmptyLower, DXIL::OpCode::LinAlgMatrixLoadFromMemory}, - {IntrinsicOp::IOP___builtin_LinAlg_MatrixSetElement, EmptyLower, - DXIL::OpCode::LinAlgMatrixSetElement}, - {IntrinsicOp::IOP___builtin_LinAlg_MatrixStoreToDescriptor, EmptyLower, + {IntrinsicOp::IOP___builtin_LinAlg_MatrixSetElement, + TranslateLinAlgMatrixSetElement, DXIL::OpCode::LinAlgMatrixSetElement}, + {IntrinsicOp::IOP___builtin_LinAlg_MatrixStoreToDescriptor, + TranslateLinAlgMatrixAccumStoreToDescriptor, DXIL::OpCode::LinAlgMatrixStoreToDescriptor}, {IntrinsicOp::IOP___builtin_LinAlg_MatrixStoreToMemory, EmptyLower, DXIL::OpCode::LinAlgMatrixStoreToMemory}, - {IntrinsicOp::IOP___builtin_LinAlg_MatrixAccumulate, EmptyLower, - DXIL::OpCode::LinAlgMatrixAccumulate}, - {IntrinsicOp::IOP___builtin_LinAlg_MatrixMatrixMultiply, EmptyLower, - DXIL::OpCode::LinAlgMatrixMultiply}, + {IntrinsicOp::IOP___builtin_LinAlg_MatrixAccumulate, + TranslateLinAlgMatrixAccumulate, DXIL::OpCode::LinAlgMatrixAccumulate}, + {IntrinsicOp::IOP___builtin_LinAlg_MatrixMatrixMultiply, + TranslateLinAlgMatrixMatrixMultiply, DXIL::OpCode::LinAlgMatrixMultiply}, {IntrinsicOp::IOP___builtin_LinAlg_MatrixMatrixMultiplyAccumulate, - EmptyLower, DXIL::OpCode::LinAlgMatrixMultiplyAccumulate}, - {IntrinsicOp::IOP___builtin_LinAlg_MatrixQueryAccumulatorLayout, EmptyLower, - DXIL::OpCode::LinAlgMatrixQueryAccumulatorLayout}, - {IntrinsicOp::IOP___builtin_LinAlg_MatrixAccumulateToDescriptor, EmptyLower, + TranslateLinAlgMatrixMatrixMultiplyAccumulate, + DXIL::OpCode::LinAlgMatrixMultiplyAccumulate}, + {IntrinsicOp::IOP___builtin_LinAlg_MatrixQueryAccumulatorLayout, + TrivialNoArgOperation, DXIL::OpCode::LinAlgMatrixQueryAccumulatorLayout}, + {IntrinsicOp::IOP___builtin_LinAlg_MatrixAccumulateToDescriptor, + TranslateLinAlgMatrixAccumStoreToDescriptor, DXIL::OpCode::LinAlgMatrixAccumulateToDescriptor}, {IntrinsicOp::IOP___builtin_LinAlg_MatrixAccumulateToMemory, EmptyLower, DXIL::OpCode::LinAlgMatrixAccumulateToMemory}, - {IntrinsicOp::IOP___builtin_LinAlg_MatrixOuterProduct, EmptyLower, - DXIL::OpCode::LinAlgMatrixOuterProduct}, - {IntrinsicOp::IOP___builtin_LinAlg_MatrixVectorMultiply, EmptyLower, - DXIL::OpCode::LinAlgMatVecMul}, - {IntrinsicOp::IOP___builtin_LinAlg_MatrixVectorMultiplyAdd, EmptyLower, - DXIL::OpCode::LinAlgMatVecMulAdd}, + {IntrinsicOp::IOP___builtin_LinAlg_MatrixOuterProduct, + TranslateLinAlgMatrixOuterProduct, DXIL::OpCode::LinAlgMatrixOuterProduct}, + {IntrinsicOp::IOP___builtin_LinAlg_MatrixVectorMultiply, + TranslateLinAlgMatVecMul, DXIL::OpCode::LinAlgMatVecMul}, + {IntrinsicOp::IOP___builtin_LinAlg_MatrixVectorMultiplyAdd, + TranslateLinAlgMatVecMulAdd, DXIL::OpCode::LinAlgMatVecMulAdd}, + {IntrinsicOp::IOP_DebugBreak, TrivialNoArgOperation, DXIL::OpCode::DebugBreak}, {IntrinsicOp::IOP_DxIsDebuggerPresent, TranslateWaveToVal, diff --git a/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/fillmatrix/nominal.hlsl b/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/fillmatrix/nominal.hlsl new file mode 100644 index 0000000000..09fc6629c3 --- /dev/null +++ b/tools/clang/test/CodeGenDXIL/hlsl/linalg/builtins/fillmatrix/nominal.hlsl @@ -0,0 +1,14 @@ +// REQUIRES: dxil-1-10 +// RUN: %dxc -T cs_6_10 -E main %s | FileCheck %s + +[numthreads(1,1,1)] +void main() { + // CHECK-LABEL: define void @main() + + // CHECK: %{{.*}} = call %dx.types.LinAlgMatrixC4M5N4U1S2 @dx.op.linAlgFillMatrix.mC4M5N4U1S2.i32(i32 -2147483636, i32 {{.*}}) ; LinAlgFillMatrix(value) + __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(4, 5, 4, 1, 2)]] mat1; + __builtin_LinAlg_FillMatrix(mat1, 5); + // CHECK: %{{.*}} = call %dx.types.LinAlgMatrixC5M3N4U0S0 @dx.op.linAlgFillMatrix.mC5M3N4U0S0.f32(i32 -2147483636, float {{.*}}) ; LinAlgFillMatrix(value) + __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(5, 3, 4, 0, 0)]] mat2; + __builtin_LinAlg_FillMatrix(mat2, 3.14); +} diff --git a/tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/ast.hlsl b/tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/ast.hlsl new file mode 100644 index 0000000000..dd8f8afec8 --- /dev/null +++ b/tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/ast.hlsl @@ -0,0 +1,15 @@ +// REQUIRES: dxil-1-10 +// RUN: %dxc -T lib_6_10 -E main %s -ast-dump-implicit | FileCheck %s + +// CHECK: FunctionDecl {{.*}} implicit used __builtin_LinAlg_FillMatrix 'void (__builtin_LinAlgMatrix & {{.*}}, unsigned int)' extern +// CHECK-NEXT: ParmVarDecl {{.*}} ret '__builtin_LinAlgMatrix &&__restrict {{.*}}' +// CHECK-NEXT: ParmVarDecl {{.*}} value 'unsigned int' +// CHECK-NEXT: HLSLIntrinsicAttr {{.*}} Implicit "op" "" 406 +// CHECK-NEXT: AvailabilityAttr {{.*}} Implicit 6.10 0 0 "" + +[shader("compute")] +[numthreads(1,1,1)] +void main() { + __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(1, 5, 4, 2, 2)]] mat; + __builtin_LinAlg_FillMatrix(mat, 15); +} diff --git a/tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/errors.hlsl b/tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/errors.hlsl new file mode 100644 index 0000000000..23c344aafb --- /dev/null +++ b/tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/errors.hlsl @@ -0,0 +1,216 @@ +// REQUIRES: dxil-1-10 +// RUN: not %dxc -T lib_6_10 %s 2>&1 | FileCheck %s + +// CHECK: Opcode LinAlgFillMatrix not valid in shader model lib_6_10(gs). +// CHECK-NEXT: note: at {{.*}} @dx.op.linAlgFillMatrix{{.*}} of function 'mainGS'. +// CHECK-NEXT: Opcode LinAlgFillMatrix not valid in shader model lib_6_10(ds). +// CHECK-NEXT: note: at {{.*}} @dx.op.linAlgFillMatrix{{.*}} of function 'mainDS'. +// CHECK-NEXT: Opcode LinAlgFillMatrix not valid in shader model lib_6_10(hs). +// CHECK-NEXT: note: at {{.*}} @dx.op.linAlgFillMatrix{{.*}} of function 'mainHS'. +// CHECK-NEXT: Opcode LinAlgFillMatrix not valid in shader model lib_6_10(vs). +// CHECK-NEXT: note: at {{.*}} @dx.op.linAlgFillMatrix{{.*}} of function 'mainVS'. +// CHECK-NEXT: Opcode LinAlgFillMatrix not valid in shader model lib_6_10(ps). +// CHECK-NEXT: note: at {{.*}} @dx.op.linAlgFillMatrix{{.*}} of function 'mainPS'. +// CHECK-NEXT: Opcode LinAlgFillMatrix not valid in shader model lib_6_10(miss). +// CHECK-NEXT: note: at {{.*}} @dx.op.linAlgFillMatrix{{.*}} of function '{{.*}}mainMS@@YAXURayPayload@@@Z'. +// CHECK-NEXT: Opcode LinAlgFillMatrix not valid in shader model lib_6_10(closesthit). +// CHECK-NEXT: note: at {{.*}} @dx.op.linAlgFillMatrix{{.*}} of function '{{.*}}mainCH@@YAXURayPayload@@UAttribs@@@Z'. +// CHECK-NEXT: Opcode LinAlgFillMatrix not valid in shader model lib_6_10(anyhit). +// CHECK-NEXT: note: at {{.*}} @dx.op.linAlgFillMatrix{{.*}} of function '{{.*}}mainAH@@YAXURayPayload@@UAttribs@@@Z'. +// CHECK-NEXT: Opcode LinAlgFillMatrix not valid in shader model lib_6_10(callable). +// CHECK-NEXT: note: at {{.*}} @dx.op.linAlgFillMatrix{{.*}} of function '{{.*}}mainCALL@@YAXUAttribs@@@Z'. +// CHECK-NEXT: Opcode LinAlgFillMatrix not valid in shader model lib_6_10(intersection). +// CHECK-NEXT: note: at {{.*}} @dx.op.linAlgFillMatrix{{.*}} of function '{{.*}}mainIS@@YAXXZ'. +// CHECK-NEXT: Opcode LinAlgFillMatrix not valid in shader model lib_6_10(raygeneration). +// CHECK-NEXT: note: at {{.*}} @dx.op.linAlgFillMatrix{{.*}} of function '{{.*}}mainRG@@YAXXZ'. +// CHECK-NEXT: Opcode LinAlgFillMatrix not valid in shader model lib_6_10(node). +// CHECK-NEXT: note: at {{.*}} @dx.op.linAlgFillMatrix{{.*}} of function 'mainNS'. +// CHECK-NEXT: Entry function performs some operation that is incompatible with the shader stage or other entry properties. See other errors for details. +// CHECK-NEXT: Function uses features incompatible with the shader stage (node) of the entry function. +// CHECK-NEXT: Entry function performs some operation that is incompatible with the shader stage or other entry properties. See other errors for details. +// CHECK-NEXT: Function uses features incompatible with the shader stage (raygeneration) of the entry function. +// CHECK-NEXT: Entry function performs some operation that is incompatible with the shader stage or other entry properties. See other errors for details. +// CHECK-NEXT: Function uses features incompatible with the shader stage (intersection) of the entry function. +// CHECK-NEXT: Entry function performs some operation that is incompatible with the shader stage or other entry properties. See other errors for details. +// CHECK-NEXT: Function uses features incompatible with the shader stage (callable) of the entry function. +// CHECK-NEXT: Entry function performs some operation that is incompatible with the shader stage or other entry properties. See other errors for details. +// CHECK-NEXT: Function uses features incompatible with the shader stage (anyhit) of the entry function. +// CHECK-NEXT: Entry function performs some operation that is incompatible with the shader stage or other entry properties. See other errors for details. +// CHECK-NEXT: Function uses features incompatible with the shader stage (closesthit) of the entry function. +// CHECK-NEXT: Entry function performs some operation that is incompatible with the shader stage or other entry properties. See other errors for details. +// CHECK-NEXT: Function uses features incompatible with the shader stage (miss) of the entry function. +// CHECK-NEXT: Entry function performs some operation that is incompatible with the shader stage or other entry properties. See other errors for details. +// CHECK-NEXT: Function uses features incompatible with the shader stage (ps) of the entry function. +// CHECK-NEXT: Entry function performs some operation that is incompatible with the shader stage or other entry properties. See other errors for details. +// CHECK-NEXT: Function uses features incompatible with the shader stage (vs) of the entry function. +// CHECK-NEXT: Entry function performs some operation that is incompatible with the shader stage or other entry properties. See other errors for details. +// CHECK-NEXT: Function uses features incompatible with the shader stage (hs) of the entry function. +// CHECK-NEXT: Entry function performs some operation that is incompatible with the shader stage or other entry properties. See other errors for details. +// CHECK-NEXT: Function uses features incompatible with the shader stage (ds) of the entry function. +// CHECK-NEXT: Entry function performs some operation that is incompatible with the shader stage or other entry properties. See other errors for details. +// CHECK-NEXT: Function uses features incompatible with the shader stage (gs) of the entry function. +// CHECK-NEXT: Validation failed. + +void CallFunction() +{ + __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(4, 5, 4, 1, 2)]] mat; + __builtin_LinAlg_FillMatrix(mat, 15); +} + +// --- Allowed Stages --- + +[shader("compute")] +[numthreads(4,4,4)] +void mainCS(uint ix : SV_GroupIndex, uint3 id : SV_GroupThreadID) { + CallFunction(); +} + +struct Verts { + float4 position : SV_Position; +}; + +[shader("mesh")] +[NumThreads(8, 8, 2)] +[OutputTopology("triangle")] +void mainMeS(out vertices Verts verts[32], uint ix : SV_GroupIndex) { + CallFunction(); + SetMeshOutputCounts(32, 16); + Verts v = {0.0, 0.0, 0.0, 0.0}; + verts[ix] = v; +} + +struct AmpPayload { + float2 dummy; +}; + +[numthreads(8, 1, 1)] +[shader("amplification")] +void mainAS() +{ + CallFunction(); + AmpPayload pld; + pld.dummy = float2(1.0,2.0); + DispatchMesh(8, 1, 1, pld); +} + +// --- Prohibited Stages --- + +[shader("pixel")] +float4 mainPS(uint ix : SV_PrimitiveID) : SV_TARGET { + CallFunction(); + return 1.0; +} + +[shader("vertex")] +float4 mainVS(uint ix : SV_VertexID) : OUT { + CallFunction(); + return 1.0; +} + +[shader("node")] +[nodedispatchgrid(8,1,1)] +[numthreads(64,2,2)] +void mainNS() { + CallFunction(); +} + +[shader("raygeneration")] +void mainRG() { + CallFunction(); +} + +[shader("intersection")] +void mainIS() { + CallFunction(); +} + +struct Attribs { float2 barys; }; + +[shader("callable")] +void mainCALL(inout Attribs attrs) { + CallFunction(); +} + +struct [raypayload] RayPayload +{ + float elem + : write(caller,closesthit,anyhit,miss) + : read(caller,closesthit,anyhit,miss); +}; + +[shader("anyhit")] +void mainAH(inout RayPayload pld, in Attribs attrs) { + CallFunction(); +} + +[shader("closesthit")] +void mainCH(inout RayPayload pld, in Attribs attrs) { + CallFunction(); +} + +[shader("miss")] +void mainMS(inout RayPayload pld) { + CallFunction(); +} + +struct PosStruct { + float4 pos : SV_Position; +}; + +struct PCStruct +{ + float Edges[3] : SV_TessFactor; + float Inside : SV_InsideTessFactor; + float4 test : TEST; +}; + +PCStruct HSPatch(InputPatch ip, + OutputPatch op, + uint ix : SV_PrimitiveID) +{ + PCStruct a; + a.Edges[0] = ip[0].pos.w; + a.Edges[1] = ip[0].pos.w; + a.Edges[2] = ip[0].pos.w; + a.Inside = ip[0].pos.w; + return a; +} + +[shader("hull")] +[domain("tri")] +[partitioning("fractional_odd")] +[outputtopology("triangle_cw")] +[outputcontrolpoints(3)] +[patchconstantfunc("HSPatch")] +PosStruct mainHS(InputPatch p, uint ix : SV_OutputControlPointID) +{ + CallFunction(); + PosStruct s; + s.pos = p[ix].pos; + return s; +} + +[shader("domain")] +[domain("tri")] +PosStruct mainDS(const OutputPatch patch, + uint ix : SV_PrimitiveID) +{ + CallFunction(); + PosStruct v; + v.pos = patch[0].pos; + return v; +} + +float4 a; + +[shader("geometry")] +[maxvertexcount(1)] +void mainGS(triangle float4 array[3] : SV_Position, uint ix : SV_GSInstanceID, + inout PointStream OutputStream) +{ + CallFunction(); + PosStruct s; + s.pos = a; + OutputStream.Append(s); + OutputStream.RestartStrip(); +} diff --git a/tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/nominal.hlsl b/tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/nominal.hlsl new file mode 100644 index 0000000000..b9767f0d89 --- /dev/null +++ b/tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/nominal.hlsl @@ -0,0 +1,10 @@ +// REQUIRES: dxil-1-10 +// RUN: %dxc -T cs_6_10 -E main %s -verify + +// expected-no-diagnostics + +[numthreads(1,1,1)] +void main() { + __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(4, 5, 4, 1, 2)]] mat; + __builtin_LinAlg_FillMatrix(mat, 5); +} diff --git a/tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/unavailable_pre_sm610.hlsl b/tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/unavailable_pre_sm610.hlsl new file mode 100644 index 0000000000..48f01ae493 --- /dev/null +++ b/tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/unavailable_pre_sm610.hlsl @@ -0,0 +1,9 @@ +// RUN: %dxc -I %hlsl_headers -T cs_6_9 -E main %s -verify + +[numthreads(4,1,1)] +void main() { + __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(1, 5, 4, 0, 0)]] mat; + + // expected-error@+1{{intrinsic __builtin_LinAlg_FillMatrix potentially used by ''main'' requires shader model 6.10 or greater}} + __builtin_LinAlg_FillMatrix(mat, 1); +} From cd1a46031bc0d9383f997051f90a807af1b0dcf3 Mon Sep 17 00:00:00 2001 From: Ashley Coleman Date: Mon, 23 Feb 2026 17:31:52 -0700 Subject: [PATCH 2/2] Address comments --- include/dxc/DXIL/DxilConstants.h | 1 + lib/DXIL/DxilModule.cpp | 1 + lib/DXIL/DxilUtil.cpp | 5 +++-- tools/clang/lib/CodeGen/CGHLSLMS.cpp | 3 ++- .../hlsl/linalg/builtins/fillmatrix/nominal.hlsl | 10 ---------- 5 files changed, 7 insertions(+), 13 deletions(-) delete mode 100644 tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/nominal.hlsl diff --git a/include/dxc/DXIL/DxilConstants.h b/include/dxc/DXIL/DxilConstants.h index eb38ec6e70..1e6c272b96 100644 --- a/include/dxc/DXIL/DxilConstants.h +++ b/include/dxc/DXIL/DxilConstants.h @@ -2500,6 +2500,7 @@ extern const char *kDxBreakFuncName; extern const char *kDxBreakCondName; extern const char *kDxBreakMDName; extern const char *kDxIsHelperGlobalName; +extern const char *kDxLinAlgMatrixTypePrefix; extern const char *kHostLayoutTypePrefix; diff --git a/lib/DXIL/DxilModule.cpp b/lib/DXIL/DxilModule.cpp index 61e1923ca1..b51729e63d 100644 --- a/lib/DXIL/DxilModule.cpp +++ b/lib/DXIL/DxilModule.cpp @@ -82,6 +82,7 @@ const char *kDxBreakFuncName = "dx.break"; const char *kDxBreakCondName = "dx.break.cond"; const char *kDxBreakMDName = "dx.break.br"; const char *kDxIsHelperGlobalName = "dx.ishelper"; +const char *kDxLinAlgMatrixTypePrefix = "dx.types.LinAlgMatrix"; const char *kHostLayoutTypePrefix = "hostlayout."; diff --git a/lib/DXIL/DxilUtil.cpp b/lib/DXIL/DxilUtil.cpp index 082bcf0831..fb7d68d73a 100644 --- a/lib/DXIL/DxilUtil.cpp +++ b/lib/DXIL/DxilUtil.cpp @@ -10,6 +10,7 @@ /////////////////////////////////////////////////////////////////////////////// #include "dxc/DXIL/DxilUtil.h" +#include "dxc/DXIL/DxilConstants.h" #include "dxc/DXIL/DxilInstructions.h" #include "dxc/DXIL/DxilModule.h" #include "dxc/DXIL/DxilOperations.h" @@ -623,11 +624,11 @@ bool IsHLSLLinAlgMatrixType(llvm::Type *Ty) { return false; if (!ST->hasName()) return false; - return ST->getName().startswith("dx.types.LinAlgMatrix"); + return ST->getName().startswith(DXIL::kDxLinAlgMatrixTypePrefix); } StringRef GetHLSLLinAlgMatrixTypeMangling(llvm::StructType *Ty) { - return Ty->getStructName().substr(sizeof("dx.types.LinAlgMatrix") - 1); + return Ty->getStructName().substr(strlen(DXIL::kDxLinAlgMatrixTypePrefix)); } bool IsHLSLResourceDescType(llvm::Type *Ty) { diff --git a/tools/clang/lib/CodeGen/CGHLSLMS.cpp b/tools/clang/lib/CodeGen/CGHLSLMS.cpp index 8b17828502..6b2d84d24e 100644 --- a/tools/clang/lib/CodeGen/CGHLSLMS.cpp +++ b/tools/clang/lib/CodeGen/CGHLSLMS.cpp @@ -14,6 +14,7 @@ #include "CGRecordLayout.h" #include "CodeGenFunction.h" #include "CodeGenModule.h" +#include "dxc/DXIL/DxilConstants.h" #include "dxc/DXIL/DxilOperations.h" #include "dxc/DXIL/DxilTypeSystem.h" #include "dxc/DXIL/DxilUtil.h" @@ -6621,7 +6622,7 @@ llvm::Type *CGMSHLSLRuntime::ConvertAttributedLinAlgMatrixType( llvm::SmallString<64> Buf; llvm::raw_svector_ostream OS(Buf); - OS << "dx.types.LinAlgMatrix"; + OS << DXIL::kDxLinAlgMatrixTypePrefix; T->appendMangledAttributes(OS); StringRef TypeName = OS.str(); diff --git a/tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/nominal.hlsl b/tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/nominal.hlsl deleted file mode 100644 index b9767f0d89..0000000000 --- a/tools/clang/test/SemaHLSL/hlsl/linalg/builtins/fillmatrix/nominal.hlsl +++ /dev/null @@ -1,10 +0,0 @@ -// REQUIRES: dxil-1-10 -// RUN: %dxc -T cs_6_10 -E main %s -verify - -// expected-no-diagnostics - -[numthreads(1,1,1)] -void main() { - __builtin_LinAlgMatrix [[__LinAlgMatrix_Attributes(4, 5, 4, 1, 2)]] mat; - __builtin_LinAlg_FillMatrix(mat, 5); -}