From ac9a828e6ee296e4814064c3aecd9883a3db2a1d Mon Sep 17 00:00:00 2001 From: David Neto Date: Thu, 4 Jan 2018 18:52:38 -0500 Subject: [PATCH] dead branch elim: Track killed backedges When deleting branches and blocks, also remove them from the backedges set, in case they were there. This prevents us from keeping stale pointers to deleted Instruction objects. That memory could be used later by another instruction, incorrectly signaling that something has a backedge reference, and the dead branch eliminator could end up deleting live blocks. Adds accessor method ir::BasicBlock::terminator Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/1168 --- source/opt/basic_block.h | 3 +++ source/opt/dead_branch_elim_pass.cpp | 3 +++ 2 files changed, 6 insertions(+) diff --git a/source/opt/basic_block.h b/source/opt/basic_block.h index 751b3a2..3e3a347 100644 --- a/source/opt/basic_block.h +++ b/source/opt/basic_block.h @@ -143,6 +143,9 @@ class BasicBlock { // this block, if any. If none, returns zero. uint32_t ContinueBlockIdIfAny() const; + // Returns the terminator instruction. Assumes the terminator exists. + Instruction* terminator() { return &*tail(); } + // Returns true if this basic block exits this function and returns to its // caller. bool IsReturn() const { return ctail()->IsReturn(); } diff --git a/source/opt/dead_branch_elim_pass.cpp b/source/opt/dead_branch_elim_pass.cpp index e165c51..a8c3068 100644 --- a/source/opt/dead_branch_elim_pass.cpp +++ b/source/opt/dead_branch_elim_pass.cpp @@ -220,6 +220,7 @@ bool DeadBranchElimPass::EliminateDeadBranches(ir::Function* func) { const uint32_t mergeLabId = mergeInst->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx); AddBranch(liveLabId, *bi); + backedges_.erase(br); context()->KillInst(br); context()->KillInst(mergeInst); @@ -232,6 +233,7 @@ bool DeadBranchElimPass::EliminateDeadBranches(ir::Function* func) { while (dLabId != mergeLabId) { if (!HasNonPhiNonBackedgeRef(dLabId)) { // Kill use/def for all instructions and mark block for elimination + backedges_.erase((*dbi)->terminator()); KillAllInsts(*dbi); elimBlocks.insert(*dbi); } @@ -242,6 +244,7 @@ bool DeadBranchElimPass::EliminateDeadBranches(ir::Function* func) { // If merge block is unreachable, continue eliminating blocks until // a live block or last block is reached. while (!HasNonPhiNonBackedgeRef(dLabId)) { + backedges_.erase((*dbi)->terminator()); KillAllInsts(*dbi); elimBlocks.insert(*dbi); ++dbi; -- 2.7.4