From 66a14f9c410dd381e478897789d60bc8510be6ee Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Mon, 1 Jun 2020 18:01:05 -0500 Subject: [PATCH] spirv: Run repair_ssa if there are discard instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SPIR-V's OpKill is a control-flow instruction but NIR's discard is not. Therefore, it can be valid SPIR-V to have if (...) { foo = /* something */ } else { discard; } use(foo); without any phi between the definition of foo and its use. This is not true in NIR, however, because NIR's discard isn't considered control-flow. Arguably, this is a NIR bug but making discard control- flow is a very deep change that can have serious ans subtle side-effects. The easier thing to do is just fix up the SSA in case we have an OpKill which might have gotten us into the above case. Fixes dEQP-VK.graphicsfuzz.vectors-and-discard-in-function with the new NIR dominance validation pass enabled. Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Daniel Schürmann Part-of: (cherry picked from commit 7cedc4128a1f9d8ecae00ff41ccf1b63e4f3ebd0) --- .pick_status.json | 2 +- src/compiler/spirv/vtn_cfg.c | 3 ++- src/compiler/spirv/vtn_private.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index fffc404ff2b..775dfc2fbb5 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -1048,7 +1048,7 @@ "description": "spirv: Run repair_ssa if there are discard instructions", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "master_sha": null, "because_sha": null }, diff --git a/src/compiler/spirv/vtn_cfg.c b/src/compiler/spirv/vtn_cfg.c index 04eca9baa24..10fe5369eef 100644 --- a/src/compiler/spirv/vtn_cfg.c +++ b/src/compiler/spirv/vtn_cfg.c @@ -616,6 +616,7 @@ vtn_process_block(struct vtn_builder *b, return NULL; case SpvOpKill: + b->has_kill = true; block->branch_type = vtn_branch_type_discard; return NULL; @@ -1185,7 +1186,7 @@ vtn_function_emit(struct vtn_builder *b, struct vtn_function *func, * but instructions in the continue may use SSA defs in the loop body. * Therefore, we need to repair SSA to insert the needed phi nodes. */ - if (b->has_loop_continue) + if (b->has_loop_continue || b->has_kill) nir_repair_ssa_impl(func->impl); func->emitted = true; diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h index 69dbe890938..e8cb65a6697 100644 --- a/src/compiler/spirv/vtn_private.h +++ b/src/compiler/spirv/vtn_private.h @@ -679,6 +679,7 @@ struct vtn_builder { unsigned func_param_idx; bool has_loop_continue; + bool has_kill; /* false by default, set to true by the ContractionOff execution mode */ bool exact;