From c5692d55799d56d83c69943c5208a8d6ab4374fd Mon Sep 17 00:00:00 2001 From: David Browne Date: Sun, 30 Aug 2026 23:33:11 +0200 Subject: [PATCH] [SPIRV] Fix sign() result type for uint matrices HLSL's sign() returns a signed integer matrix for an unsigned integer matrix argument. SPIR-V codegen instead used the argument composite's type as the result type of OpCompositeConstruct, constructing an unsigned composite from signed vector constituents, which fails validation. Pass the call expression's result type to processEachVectorInMatrix so the composite is constructed with the intrinsic's signed result type, fixing the validation error. This issue affected all uintMxN matrices with M,N > 1. Fixes microsoft/DirectXShaderCompiler#8858 --- tools/clang/lib/SPIRV/SpirvEmitter.cpp | 5 +++-- tools/clang/test/CodeGenSPIRV/intrinsics.uintsign.hlsl | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.cpp b/tools/clang/lib/SPIRV/SpirvEmitter.cpp index f05c0d9553..b08f94cdae 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.cpp +++ b/tools/clang/lib/SPIRV/SpirvEmitter.cpp @@ -13117,8 +13117,9 @@ SpirvEmitter::processIntrinsicSignUnsignedInt(const CallExpr *callExpr) { if (isVectorType(firstArgType)) { return actOnEachVec(0, firstArgType, callExpr->getType(), doExpr(firstArg)); } - return processEachVectorInMatrix(firstArg, doExpr(firstArg), actOnEachVec, - srcLoc, srcRange); + return processEachVectorInMatrix(firstArg, callExpr->getType(), + doExpr(firstArg), actOnEachVec, srcLoc, + srcRange); } SpirvInstruction * diff --git a/tools/clang/test/CodeGenSPIRV/intrinsics.uintsign.hlsl b/tools/clang/test/CodeGenSPIRV/intrinsics.uintsign.hlsl index 454a9c004f..3f70ff86f8 100644 --- a/tools/clang/test/CodeGenSPIRV/intrinsics.uintsign.hlsl +++ b/tools/clang/test/CodeGenSPIRV/intrinsics.uintsign.hlsl @@ -67,7 +67,7 @@ void main() { // CHECK-NEXT: [[h_row2:%[0-9]+]] = OpCompositeExtract %v3uint [[h]] 2 // CHECK-NEXT: [[cmp_h_row2:%[0-9]+]] = OpUGreaterThan %v3bool [[h_row2]] [[zeros_uint3]] // CHECK-NEXT: [[select_h_row2:%[0-9]+]] = OpSelect %v3int [[cmp_h_row2]] [[ones_int3]] [[zeros_int3]] -// CHECK-NEXT: [[select_h:%[0-9]+]] = OpCompositeConstruct %_arr_v3uint_uint_3 [[select_h_row0]] [[select_h_row1]] [[select_h_row2]] +// CHECK-NEXT: [[select_h:%[0-9]+]] = OpCompositeConstruct %_arr_v3int_uint_3 [[select_h_row0]] [[select_h_row1]] [[select_h_row2]] // CHECK-NEXT: OpStore %result3x3 [[select_h]] uint3x3 h; result3x3 = sign(h);