fix(joinir): Pattern 4 PHI loss fix with exit_bindings and block reuse
Two root causes for Pattern 4 outputting 0 instead of 25: 1. instruction_rewriter.rs:92 - BasicBlock::new() was overwriting existing blocks that already contained PHI instructions from JoinIR Select lowering. Fixed by removing and reusing existing blocks instead of creating new ones. 2. pattern4_with_continue.rs - JoinIR exit PHI (ValueId 15) was not connected to host's sum variable, causing DCE to eliminate the PHI as "unused". Fixed by using new_with_exit_bindings() with explicit LoopExitBinding to connect k_exit's sum_exit to host's sum slot. Test result: loop_continue_pattern4.hako now correctly outputs 25. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -89,7 +89,15 @@ pub(super) fn merge_and_rewrite(
|
|||||||
let new_block_id = remapper
|
let new_block_id = remapper
|
||||||
.get_block(func_name, *old_block_id)
|
.get_block(func_name, *old_block_id)
|
||||||
.ok_or_else(|| format!("Block {:?} not found for {}", old_block_id, func_name))?;
|
.ok_or_else(|| format!("Block {:?} not found for {}", old_block_id, func_name))?;
|
||||||
let mut new_block = BasicBlock::new(new_block_id);
|
|
||||||
|
// Phase 195 FIX: Reuse existing block if present (preserves PHI from JoinIR Select lowering)
|
||||||
|
// ultrathink "finalizer集約案": Don't overwrite blocks with BasicBlock::new()
|
||||||
|
let mut new_block = if let Some(ref mut current_func) = builder.current_function {
|
||||||
|
current_func.blocks.remove(&new_block_id)
|
||||||
|
.unwrap_or_else(|| BasicBlock::new(new_block_id))
|
||||||
|
} else {
|
||||||
|
BasicBlock::new(new_block_id)
|
||||||
|
};
|
||||||
|
|
||||||
// Phase 189 FIX: Check if this is entry function's entry block (for boundary input skipping)
|
// Phase 189 FIX: Check if this is entry function's entry block (for boundary input skipping)
|
||||||
let is_entry_func_entry_block =
|
let is_entry_func_entry_block =
|
||||||
|
|||||||
@ -182,10 +182,18 @@ impl MirBuilder {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Merge JoinIR blocks into current function
|
// Merge JoinIR blocks into current function
|
||||||
// Phase 195: Create and pass JoinInlineBoundary for Pattern 4
|
// Phase 195 FIX: Use exit_bindings to connect k_exit's sum_exit to host's sum variable
|
||||||
let boundary = crate::mir::join_ir::lowering::inline_boundary::JoinInlineBoundary::new_inputs_only(
|
// Pattern 4: k_exit(sum_exit) returns sum_exit, so we bind ValueId(15) to host's sum
|
||||||
|
let boundary = crate::mir::join_ir::lowering::inline_boundary::JoinInlineBoundary::new_with_exit_bindings(
|
||||||
vec![ValueId(0), ValueId(1)], // JoinIR's main() parameters (i_init, sum_init)
|
vec![ValueId(0), ValueId(1)], // JoinIR's main() parameters (i_init, sum_init)
|
||||||
vec![loop_var_id, sum_var_id], // Host's loop variables
|
vec![loop_var_id, sum_var_id], // Host's loop variables
|
||||||
|
vec![
|
||||||
|
crate::mir::join_ir::lowering::inline_boundary::LoopExitBinding {
|
||||||
|
carrier_name: "sum".to_string(),
|
||||||
|
join_exit_value: ValueId(15), // k_exit's parameter (sum_exit)
|
||||||
|
host_slot: sum_var_id, // variable_map["sum"]
|
||||||
|
}
|
||||||
|
],
|
||||||
);
|
);
|
||||||
// Phase 195: Capture exit PHI result (Pattern 4 returns sum)
|
// Phase 195: Capture exit PHI result (Pattern 4 returns sum)
|
||||||
let result_val = self.merge_joinir_mir_blocks(&mir_module, Some(&boundary), debug)?;
|
let result_val = self.merge_joinir_mir_blocks(&mir_module, Some(&boundary), debug)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user