fix(mir): conservative PHI box for If/Loop and Stage1 resolver SSA
This commit is contained in:
@ -331,8 +331,15 @@ impl LoopFormBuilder {
|
||||
.push((branch_source_block, carrier.header_phi));
|
||||
}
|
||||
|
||||
// 📦 Hotfix 6: Get actual CFG predecessors for exit block
|
||||
let exit_preds = ops.get_block_predecessors(exit_id);
|
||||
if debug {
|
||||
eprintln!("[DEBUG/exit_phi] Exit block predecessors: {:?}", exit_preds);
|
||||
}
|
||||
|
||||
// Add break snapshot values
|
||||
// 📦 Hotfix 2: Skip non-existent blocks (幽霊ブロック対策)
|
||||
// 📦 Hotfix 6: Skip blocks not in CFG predecessors (unreachable continuation対策)
|
||||
for (block_id, snapshot) in exit_snapshots {
|
||||
// Validate block existence before adding to PHI inputs
|
||||
if !ops.block_exists(*block_id) {
|
||||
@ -342,6 +349,15 @@ impl LoopFormBuilder {
|
||||
continue; // Skip ghost blocks
|
||||
}
|
||||
|
||||
// Hotfix 6: Skip blocks not in actual CFG predecessors
|
||||
// This catches unreachable continuation blocks created after break/continue
|
||||
if !exit_preds.contains(block_id) {
|
||||
if debug {
|
||||
eprintln!("[DEBUG/exit_phi] ⚠️ Skipping block {:?} (not in CFG predecessors)", block_id);
|
||||
}
|
||||
continue; // Skip blocks not actually branching to exit
|
||||
}
|
||||
|
||||
for (var_name, &value) in snapshot {
|
||||
all_vars
|
||||
.entry(var_name.clone())
|
||||
@ -409,6 +425,11 @@ pub trait LoopFormOps {
|
||||
/// Used to skip non-existent blocks when building exit PHIs.
|
||||
fn block_exists(&self, block: BasicBlockId) -> bool;
|
||||
|
||||
/// 📦 Get actual CFG predecessors for a block (Hotfix 6: PHI input validation)
|
||||
/// Returns the set of blocks that actually branch to this block in the CFG.
|
||||
/// Used to validate exit PHI inputs against actual control flow.
|
||||
fn get_block_predecessors(&self, block: BasicBlockId) -> std::collections::HashSet<BasicBlockId>;
|
||||
|
||||
/// Check if a variable is a function parameter
|
||||
fn is_parameter(&self, name: &str) -> bool;
|
||||
|
||||
@ -520,6 +541,11 @@ mod tests {
|
||||
true
|
||||
}
|
||||
|
||||
fn get_block_predecessors(&self, _block: BasicBlockId) -> std::collections::HashSet<BasicBlockId> {
|
||||
// MockOps: return empty set (no CFG in test)
|
||||
std::collections::HashSet::new()
|
||||
}
|
||||
|
||||
fn is_parameter(&self, name: &str) -> bool {
|
||||
self.params.iter().any(|p| p == name)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user