From a87b1efbd2c691b574f35a7ae0a1df96e5a588cf Mon Sep 17 00:00:00 2001 From: Elizabeth Figura <zfigura@codeweavers.com> Date: Mon, 10 Mar 2025 16:51:20 -0500 Subject: [PATCH] vkd3d-shader/hlsl: Don't invalidate OOB constant derefs. --- libs/vkd3d-shader/hlsl_codegen.c | 13 +++++++++++-- tests/hlsl/hard-copy-prop.shader_test | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 1241f7622..aac4e4c04 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1627,9 +1627,18 @@ static void copy_propagation_invalidate_variable_from_deref_recurse(struct hlsl_ if (path_node->type == HLSL_IR_CONSTANT) { + uint32_t index = hlsl_ir_constant(path_node)->value.u[0].u; + + /* Don't bother invalidating anything if the index is constant but + * out-of-range. + * Such indices are illegal in HLSL, but only if the code is not + * dead, and we can't always know if code is dead without copy-prop + * itself. */ + if (index >= hlsl_type_element_count(type)) + return; + copy_propagation_invalidate_variable_from_deref_recurse(ctx, var_def, deref, subtype, - depth + 1, hlsl_ir_constant(path_node)->value.u[0].u * subtype_comp_count, - writemask, time); + depth + 1, index * subtype_comp_count, writemask, time); } else { diff --git a/tests/hlsl/hard-copy-prop.shader_test b/tests/hlsl/hard-copy-prop.shader_test index 55f6f6fa9..3af552fad 100644 --- a/tests/hlsl/hard-copy-prop.shader_test +++ b/tests/hlsl/hard-copy-prop.shader_test @@ -186,3 +186,22 @@ if(sm<4) uniform 8 float4 1 0 0 0 if(sm>=4) uniform 8 uint4 1 0 0 0 todo(msl) draw quad probe (0, 0) rgba(3.0, 3.0, 3.0, 3.0) + +% OOB indexes are illegal, but sm < 6 allows them in dead code. +% We need copy-prop to know if the code is dead. +% This means copy-prop needs to be able to handle OOB indexes. +[pixel shader fail(sm>=6)] + +float4 main() : sv_target +{ + static float4 arr[4]; + bool x = false; + + if (x) + { + arr[100] = 0; + return arr[100]; + } + + return 0; +} -- GitLab