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