diff --git a/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs b/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs index 9ad0c4c8..df6418bd 100644 --- a/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs +++ b/src/mir/builder/control_flow/joinir/merge/instruction_rewriter.rs @@ -872,6 +872,42 @@ fn plan_rewrites( "[plan_rewrites] ExitJump (skippable): redirecting from {:?} to exit_block_id {:?}", target_block, ctx.exit_block_id ); + + // Phase 286C-4.1: Collect carrier_inputs for skippable exit jump + // This was missing in the refactored code + if let Some(b) = boundary { + for binding in &b.exit_bindings { + // Skip ConditionOnly carriers + if binding.role == crate::mir::join_ir::lowering::carrier_info::CarrierRole::ConditionOnly { + continue; + } + + // Try to get carrier value from header PHI + if let Some(phi_dst) = loop_header_phi_info.get_carrier_phi(&binding.carrier_name) { + result.carrier_inputs + .entry(binding.carrier_name.clone()) + .or_insert_with(Vec::new) + .push((new_block_id, phi_dst)); + log!( + verbose, + "[plan_rewrites] ExitJump carrier '{}': from {:?} value {:?}", + binding.carrier_name, new_block_id, phi_dst + ); + } else if b.exit_reconnect_mode == crate::mir::join_ir::lowering::carrier_info::ExitReconnectMode::DirectValue { + // DirectValue fallback: use host_slot + result.carrier_inputs + .entry(binding.carrier_name.clone()) + .or_insert_with(Vec::new) + .push((new_block_id, binding.host_slot)); + log!( + verbose, + "[plan_rewrites] ExitJump DirectValue fallback for '{}': host_slot {:?}", + binding.carrier_name, binding.host_slot + ); + } + } + } + ctx.exit_block_id } else { log!(