From 32b6c63485626f10b3bc8efb0239064cc781115e Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Wed, 17 Mar 2021 01:33:25 -0300
Subject: shader: Reorder phi nodes when redefined as undefined opcodes

---
 src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

(limited to 'src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp')

diff --git a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
index f89fd51c8a..d09bcec366 100644
--- a/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
+++ b/src/shader_recompiler/ir_opt/ssa_rewrite_pass.cpp
@@ -181,8 +181,16 @@ private:
         }
         if (same.IsEmpty()) {
             // The phi is unreachable or in the start block
-            const auto first_not_phi{std::ranges::find_if_not(block->Instructions(), IsPhi)};
+            // First remove the phi node from the block, it will be reinserted
+            IR::Block::InstructionList& list{block->Instructions()};
+            list.erase(IR::Block::InstructionList::s_iterator_to(phi));
+
+            // Insert an undef instruction after all phi nodes (to keep phi instructions on top)
+            const auto first_not_phi{std::ranges::find_if_not(list, IsPhi)};
             same = IR::Value{&*block->PrependNewInst(first_not_phi, undef_opcode)};
+
+            // Insert the phi node after the undef opcode, this will be replaced with an identity
+            list.insert(first_not_phi, phi);
         }
         // Reroute all uses of phi to same and remove phi
         phi.ReplaceUsesWith(same);
-- 
cgit v1.2.3-70-g09d2