diff --git a/src/mir/builder/control_flow.rs b/src/mir/builder/control_flow.rs index 3c06d701..0a3d6cd6 100644 --- a/src/mir/builder/control_flow.rs +++ b/src/mir/builder/control_flow.rs @@ -402,14 +402,20 @@ impl super::MirBuilder { let mut function_entry_map: HashMap = HashMap::new(); // 1. Allocate new block IDs for ALL functions (Phase 189) + // DETERMINISM FIX: Sort functions by name to ensure consistent iteration order if debug { eprintln!("[cf_loop/joinir] Phase 189: Allocating block IDs for all functions"); } - for (func_name, func) in &mir_module.functions { + let mut functions: Vec<_> = mir_module.functions.iter().collect(); + functions.sort_by_key(|(name, _)| name.as_str()); + for (func_name, func) in functions { if debug { eprintln!("[cf_loop/joinir] Function: {}", func_name); } - for old_block_id in func.blocks.keys() { + // DETERMINISM FIX: Sort blocks by ID to ensure consistent iteration order + let mut blocks: Vec<_> = func.blocks.iter().collect(); + blocks.sort_by_key(|(id, _)| id.0); + for (old_block_id, _) in blocks { let new_block_id = self.block_gen.next(); // Use composite key to avoid collision between functions block_map.insert((func_name.clone(), *old_block_id), new_block_id); @@ -485,11 +491,14 @@ impl super::MirBuilder { } // 5. Merge ALL functions (Phase 189: iterate over all, not just first) + // DETERMINISM FIX: Sort functions by name to ensure consistent iteration order if debug { eprintln!("[cf_loop/joinir] Phase 189: Merging {} functions", mir_module.functions.len()); } // Phase 189: Iterate over both names and functions (need name for composite keys) - for (func_name, func) in &mir_module.functions { + let mut functions_merge: Vec<_> = mir_module.functions.iter().collect(); + functions_merge.sort_by_key(|(name, _)| name.as_str()); + for (func_name, func) in functions_merge { if debug { eprintln!( "[cf_loop/joinir] Merging function '{}' with {} blocks, entry={:?}", @@ -507,7 +516,10 @@ impl super::MirBuilder { } // Clone and remap all blocks from this function - for (old_block_id, old_block) in &func.blocks { + // DETERMINISM FIX: Sort blocks by ID to ensure consistent iteration order + let mut blocks_merge: Vec<_> = func.blocks.iter().collect(); + blocks_merge.sort_by_key(|(id, _)| id.0); + for (old_block_id, old_block) in blocks_merge { // Use composite key to get correct mapping for this function's block let new_block_id = block_map[&(func_name.clone(), *old_block_id)]; let mut new_block = BasicBlock::new(new_block_id);