From 31eb152917f3f1e1c6cf31e5449dabddcfa06fbd Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Tue, 2 Sep 2025 18:27:25 +0200 Subject: [PATCH] vkd3d-shader/ir: Require signed operands for ISHR instructions. --- libs/vkd3d-shader/dxil.c | 9 ++++-- libs/vkd3d-shader/ir.c | 39 +++++++++++++++++++---- tests/hlsl/bitwise-assignment.shader_test | 2 +- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 63dcbd3c0..f5b7202c9 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -4627,6 +4627,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco struct vkd3d_shader_src_param *src_params; enum vkd3d_shader_opcode handler_idx; const struct sm6_value *a, *b; + uint32_t type_flags = 0; uint64_t code, flags; bool silence_warning; unsigned int i = 0; @@ -4668,6 +4669,8 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco silence_warning = !(flags & ~(OB_NO_UNSIGNED_WRAP | OB_NO_SIGNED_WRAP)); break; case VSIR_OP_ISHR: + type_flags |= DXIL_TYPE_SIGNED; + /* fall through */ case VSIR_OP_USHR: case VSIR_OP_IDIV: case VSIR_OP_UDIV_SIMPLE: @@ -4692,8 +4695,8 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; - src_param_init_from_value(&src_params[0], a, 0, sm6); - src_param_init_from_value(&src_params[1], b, 0, sm6); + src_param_init_from_value(&src_params[0], a, type_flags, sm6); + src_param_init_from_value(&src_params[1], b, type_flags, sm6); if (code == BINOP_SUB) src_params[1].modifiers = VKD3DSPSM_NEG; @@ -4706,7 +4709,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco * do. */ ins->flags |= VKD3DSI_SHIFT_UNMASKED; } - instruction_dst_param_init_ssa_scalar(ins, 0, sm6); + instruction_dst_param_init_ssa_scalar(ins, type_flags, sm6); } static const struct sm6_block *sm6_function_get_block(const struct sm6_function *function, uint64_t index, diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 506b397fb..c6e43fddb 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -11428,19 +11428,20 @@ static void vsir_validate_cast_operation(struct validation_context *ctx, } static void vsir_validate_shift_operation(struct validation_context *ctx, - const struct vkd3d_shader_instruction *instruction) + const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) { enum vsir_data_type dst_data_type, src_data_type; - static const bool types[] = + static const bool shift_types[] = { [VSIR_DATA_I32] = true, + [VSIR_DATA_I64] = true, [VSIR_DATA_U32] = true, [VSIR_DATA_U64] = true, }; dst_data_type = instruction->dst[0].reg.data_type; - if ((size_t)dst_data_type >= ARRAY_SIZE(types) || !types[dst_data_type]) + if ((size_t)dst_data_type >= VSIR_DATA_TYPE_COUNT || !types[dst_data_type]) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid destination data type \"%s\" (%#x) for shift operation \"%s\" (%#x).", vsir_data_type_get_name(dst_data_type, ""), dst_data_type, @@ -11455,7 +11456,7 @@ static void vsir_validate_shift_operation(struct validation_context *ctx, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); src_data_type = instruction->src[1].reg.data_type; - if ((size_t)src_data_type >= ARRAY_SIZE(types) || !types[src_data_type]) + if ((size_t)src_data_type >= ARRAY_SIZE(shift_types) || !shift_types[src_data_type]) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid source operand 1 data type \"%s\" (%#x) for shift operation \"%s\" (%#x).", vsir_data_type_get_name(src_data_type, ""), src_data_type, @@ -12020,6 +12021,32 @@ static void vsir_validate_ifc(struct validation_context *ctx, const struct vkd3d vsir_validator_push_block(ctx, VSIR_OP_IF); } +static void vsir_validate_ishl(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + static const bool types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_I32] = true, + [VSIR_DATA_I64] = true, + [VSIR_DATA_U32] = true, + [VSIR_DATA_U64] = true, + }; + + vsir_validate_shift_operation(ctx, instruction, types); +} + +static void vsir_validate_ishr(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + static const bool types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_I32] = true, + [VSIR_DATA_I64] = true, + }; + + vsir_validate_shift_operation(ctx, instruction, types); +} + static void vsir_validate_itof(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { static const bool src_types[VSIR_DATA_TYPE_COUNT] = @@ -12339,8 +12366,8 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ [VSIR_OP_INEG] = {1, 1, vsir_validate_integer_elementwise_operation}, [VSIR_OP_IREM] = {1, 2, vsir_validate_integer_elementwise_operation}, [VSIR_OP_ISFINITE] = {1, 1, vsir_validate_float_comparison_operation}, - [VSIR_OP_ISHL] = {1, 2, vsir_validate_shift_operation}, - [VSIR_OP_ISHR] = {1, 2, vsir_validate_shift_operation}, + [VSIR_OP_ISHL] = {1, 2, vsir_validate_ishl}, + [VSIR_OP_ISHR] = {1, 2, vsir_validate_ishr}, [VSIR_OP_ISINF] = {1, 1, vsir_validate_float_comparison_operation}, [VSIR_OP_ISNAN] = {1, 1, vsir_validate_float_comparison_operation}, [VSIR_OP_ITOF] = {1, 1, vsir_validate_itof}, diff --git a/tests/hlsl/bitwise-assignment.shader_test b/tests/hlsl/bitwise-assignment.shader_test index 27290eb93..64b0a3cf5 100644 --- a/tests/hlsl/bitwise-assignment.shader_test +++ b/tests/hlsl/bitwise-assignment.shader_test @@ -36,7 +36,7 @@ float4 main() : SV_TARGET [test] uniform 0 uint4 1 0 0 0 draw quad -todo(msl & sm>=6) probe (0, 0) f32(2, -6, 2, -6) +probe (0, 0) f32(2, -6, 2, -6) [pixel shader] uniform uint4 nonconst;