aco: Don't remove exec writes that also write other registers.
authorTimur Kristóf <timur.kristof@gmail.com>
Sun, 2 Apr 2023 20:11:25 +0000 (22:11 +0200)
committerMarge Bot <emma+marge@anholt.net>
Mon, 3 Apr 2023 14:36:07 +0000 (14:36 +0000)
Don't eliminate an instruction that writes registers other than exec and scc.
It is possible that this is eg. an s_and_saveexec and the saved value is
used by a later branch.

Fixes: bc130497472cb4ec4ec60695ed99b169d6681118
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21493>

src/amd/compiler/aco_ssa_elimination.cpp

index c90c29b..39c33cc 100644 (file)
@@ -596,7 +596,15 @@ eliminate_useless_exec_writes_in_block(ssa_elimination_ctx& ctx, Block& block)
 
       /* See if we found an unused exec write. */
       if (writes_exec && !exec_write_used) {
-         instr.reset();
+         /* Don't eliminate an instruction that writes registers other than exec and scc.
+          * It is possible that this is eg. an s_and_saveexec and the saved value is
+          * used by a later branch.
+          */
+         bool writes_other = std::any_of(instr->definitions.begin(), instr->definitions.end(),
+                                         [](const Definition& def) -> bool
+                                         { return def.physReg() != exec && def.physReg() != scc; });
+         if (!writes_other)
+            instr.reset();
          continue;
       }