diff --git a/src/mir/builder/emission/branch.rs b/src/mir/builder/emission/branch.rs index da29ac9a..9b2b02be 100644 --- a/src/mir/builder/emission/branch.rs +++ b/src/mir/builder/emission/branch.rs @@ -5,11 +5,20 @@ use crate::mir::builder::MirBuilder; #[inline] pub fn emit_conditional(b: &mut MirBuilder, cond: crate::mir::ValueId, then_bb: BasicBlockId, else_bb: BasicBlockId) -> Result<(), String> { - b.emit_instruction(MirInstruction::Branch { condition: cond, then_bb, else_bb }) + if let (Some(func), Some(cur_bb)) = (b.current_function.as_mut(), b.current_block) { + crate::mir::ssot::cf_common::set_branch(func, cur_bb, cond, then_bb, else_bb); + Ok(()) + } else { + b.emit_instruction(MirInstruction::Branch { condition: cond, then_bb, else_bb }) + } } #[inline] pub fn emit_jump(b: &mut MirBuilder, target: BasicBlockId) -> Result<(), String> { - b.emit_instruction(MirInstruction::Jump { target }) + if let (Some(func), Some(cur_bb)) = (b.current_function.as_mut(), b.current_block) { + crate::mir::ssot::cf_common::set_jump(func, cur_bb, target); + Ok(()) + } else { + b.emit_instruction(MirInstruction::Jump { target }) + } } - diff --git a/src/mir/builder/emission/compare.rs b/src/mir/builder/emission/compare.rs index 513c7f3b..b2d0c889 100644 --- a/src/mir/builder/emission/compare.rs +++ b/src/mir/builder/emission/compare.rs @@ -5,7 +5,11 @@ use crate::mir::builder::MirBuilder; #[inline] pub fn emit_to(b: &mut MirBuilder, dst: ValueId, op: CompareOp, lhs: ValueId, rhs: ValueId) -> Result<(), String> { - b.emit_instruction(MirInstruction::Compare { dst, op, lhs, rhs })?; + if let (Some(func), Some(cur_bb)) = (b.current_function.as_mut(), b.current_block) { + crate::mir::ssot::cf_common::emit_compare_func(func, cur_bb, dst, op, lhs, rhs); + } else { + b.emit_instruction(MirInstruction::Compare { dst, op, lhs, rhs })?; + } // 比較結果は Bool 型(既存実装と同じ振る舞い) b.value_types.insert(dst, MirType::Bool); Ok(()) @@ -21,4 +25,3 @@ pub fn emit_eq_to(b: &mut MirBuilder, dst: ValueId, lhs: ValueId, rhs: ValueId) pub fn emit_ne_to(b: &mut MirBuilder, dst: ValueId, lhs: ValueId, rhs: ValueId) -> Result<(), String> { emit_to(b, dst, CompareOp::Ne, lhs, rhs) } - diff --git a/src/mir/ssot/cf_common.rs b/src/mir/ssot/cf_common.rs new file mode 100644 index 00000000..83920465 --- /dev/null +++ b/src/mir/ssot/cf_common.rs @@ -0,0 +1,57 @@ +use crate::mir::{BasicBlockId, CompareOp, MirFunction, MirInstruction, ValueId}; + +/// Emit a MIR Compare instruction into the current block (function-level SSOT helper) +pub fn emit_compare_func( + f: &mut MirFunction, + cur_bb: BasicBlockId, + dst: ValueId, + op: CompareOp, + lhs: ValueId, + rhs: ValueId, +) { + if let Some(bb) = f.get_block_mut(cur_bb) { + bb.add_instruction(MirInstruction::Compare { dst, op, lhs, rhs }); + } +} + +/// Set a conditional branch terminator on the current block and register predecessors. +pub fn set_branch( + f: &mut MirFunction, + cur_bb: BasicBlockId, + condition: ValueId, + then_bb: BasicBlockId, + else_bb: BasicBlockId, +) { + if let Some(bb) = f.get_block_mut(cur_bb) { + bb.set_terminator(MirInstruction::Branch { condition, then_bb, else_bb }); + } + if let Some(tb) = f.get_block_mut(then_bb) { + tb.add_predecessor(cur_bb); + } + if let Some(eb) = f.get_block_mut(else_bb) { + eb.add_predecessor(cur_bb); + } +} + +/// Set an unconditional jump terminator and register predecessor on target block. +pub fn set_jump(f: &mut MirFunction, cur_bb: BasicBlockId, target: BasicBlockId) { + if let Some(bb) = f.get_block_mut(cur_bb) { + bb.set_terminator(MirInstruction::Jump { target }); + } + if let Some(tb) = f.get_block_mut(target) { + tb.add_predecessor(cur_bb); + } +} + +/// Insert a PHI instruction at block head (after existing PHIs) with normalized inputs order. +pub fn insert_phi_at_head( + f: &mut MirFunction, + bb_id: BasicBlockId, + dst: ValueId, + mut inputs: Vec<(BasicBlockId, ValueId)>, +) { + inputs.sort_by_key(|(bb, _)| bb.0); + if let Some(bb) = f.get_block_mut(bb_id) { + bb.insert_instruction_after_phis(MirInstruction::Phi { dst, inputs }); + } +} diff --git a/src/mir/ssot/mod.rs b/src/mir/ssot/mod.rs index ef6ada68..29e63779 100644 --- a/src/mir/ssot/mod.rs +++ b/src/mir/ssot/mod.rs @@ -1,2 +1,3 @@ pub mod binop_lower; pub mod loop_common; +pub mod cf_common; diff --git a/src/runner/json_v0_bridge/lowering.rs b/src/runner/json_v0_bridge/lowering.rs index bd73eb83..b426be9c 100644 --- a/src/runner/json_v0_bridge/lowering.rs +++ b/src/runner/json_v0_bridge/lowering.rs @@ -118,12 +118,8 @@ impl BridgeEnv { /// Small helper: set Jump terminator and record predecessor on the target. fn jump_with_pred(f: &mut MirFunction, cur_bb: BasicBlockId, target: BasicBlockId) { - if let Some(bb) = f.get_block_mut(cur_bb) { - bb.set_terminator(MirInstruction::Jump { target }); - } - if let Some(succ) = f.get_block_mut(target) { - succ.add_predecessor(cur_bb); - } + // Delegate to SSOT CF helper for consistency + crate::mir::ssot::cf_common::set_jump(f, cur_bb, target); } /// Strip Phi instructions by inserting edge copies on each predecessor. diff --git a/src/runner/json_v0_bridge/lowering/expr.rs b/src/runner/json_v0_bridge/lowering/expr.rs index 51f61a3f..7b0406b8 100644 --- a/src/runner/json_v0_bridge/lowering/expr.rs +++ b/src/runner/json_v0_bridge/lowering/expr.rs @@ -190,14 +190,7 @@ pub(super) fn lower_expr_with_scope( _ => return Err("unsupported compare op".into()), }; let dst = f.next_value_id(); - if let Some(bb) = f.get_block_mut(cur_after_r) { - bb.add_instruction(MirInstruction::Compare { - dst, - op: cop, - lhs: l, - rhs: r, - }); - } + crate::mir::ssot::cf_common::emit_compare_func(f, cur_after_r, dst, cop, l, r); Ok((dst, cur_after_r)) } ExprV0::Logical { op, lhs, rhs } => { @@ -206,20 +199,10 @@ pub(super) fn lower_expr_with_scope( let fall_bb = new_block(f); let merge_bb = new_block(f); let is_and = matches!(op.as_str(), "&&" | "and"); - if let Some(bb) = f.get_block_mut(cur_after_l) { - if is_and { - bb.set_terminator(MirInstruction::Branch { - condition: l, - then_bb: rhs_bb, - else_bb: fall_bb, - }); - } else { - bb.set_terminator(MirInstruction::Branch { - condition: l, - then_bb: fall_bb, - else_bb: rhs_bb, - }); - } + if is_and { + crate::mir::ssot::cf_common::set_branch(f, cur_after_l, l, rhs_bb, fall_bb); + } else { + crate::mir::ssot::cf_common::set_branch(f, cur_after_l, l, fall_bb, rhs_bb); } // ARCHIVED: JIT events moved to archive/jit-cranelift/ during Phase 15 // crate::jit::events::emit_lower( @@ -229,32 +212,21 @@ pub(super) fn lower_expr_with_scope( // ); let cdst = f.next_value_id(); if let Some(bb) = f.get_block_mut(fall_bb) { - let cval = if is_and { - ConstValue::Bool(false) - } else { - ConstValue::Bool(true) - }; + let cval = if is_and { ConstValue::Bool(false) } else { ConstValue::Bool(true) }; bb.add_instruction(MirInstruction::Const { dst: cdst, value: cval }); - bb.set_terminator(MirInstruction::Jump { target: merge_bb }); } + crate::mir::ssot::cf_common::set_jump(f, fall_bb, merge_bb); let (rval, rhs_end) = lower_expr_with_scope(env, f, rhs_bb, rhs, vars)?; if let Some(bb) = f.get_block_mut(rhs_end) { if !bb.is_terminated() { - bb.set_terminator(MirInstruction::Jump { target: merge_bb }); + crate::mir::ssot::cf_common::set_jump(f, rhs_end, merge_bb); } } let out = f.next_value_id(); // フェーズM.2: PHI統一処理(no_phi分岐削除) - if let Some(bb) = f.get_block_mut(merge_bb) { - let mut inputs: Vec<(BasicBlockId, ValueId)> = vec![(fall_bb, cdst)]; - if rhs_end != fall_bb { - inputs.push((rhs_end, rval)); - } else { - inputs.push((fall_bb, rval)); - } - inputs.sort_by_key(|(bbid, _)| bbid.0); - bb.insert_instruction_after_phis(MirInstruction::Phi { dst: out, inputs }); - } + let mut inputs: Vec<(BasicBlockId, ValueId)> = vec![(fall_bb, cdst)]; + if rhs_end != fall_bb { inputs.push((rhs_end, rval)); } else { inputs.push((fall_bb, rval)); } + crate::mir::ssot::cf_common::insert_phi_at_head(f, merge_bb, out, inputs); Ok((out, merge_bb)) } ExprV0::Call { name, args } => { diff --git a/src/runner/json_v0_bridge/lowering/if_else.rs b/src/runner/json_v0_bridge/lowering/if_else.rs index f02510bf..f0d356a6 100644 --- a/src/runner/json_v0_bridge/lowering/if_else.rs +++ b/src/runner/json_v0_bridge/lowering/if_else.rs @@ -18,34 +18,26 @@ pub(super) fn lower_if_stmt( let then_bb = new_block(f); let else_bb = new_block(f); let merge_bb = new_block(f); - f.set_branch_terminator(cur, cval, then_bb, else_bb)?; + crate::mir::ssot::cf_common::set_branch(f, cur, cval, then_bb, else_bb); let base_vars = vars.clone(); let mut then_vars = base_vars.clone(); let tend = lower_stmt_list_with_vars(f, then_bb, then_body, &mut then_vars, loop_stack, env)?; let mut then_terminated = false; if let Some(bb) = f.get_block_mut(tend) { - if !bb.is_terminated() { - bb.set_terminator(MirInstruction::Jump { target: merge_bb }); - } else { - then_terminated = true; - } + if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, tend, merge_bb); } + else { then_terminated = true; } } let (else_end_pred, else_vars, else_terminated) = if let Some(elses) = else_body { let mut ev = base_vars.clone(); let eend = lower_stmt_list_with_vars(f, else_bb, elses, &mut ev, loop_stack, env)?; let mut term = false; if let Some(bb) = f.get_block_mut(eend) { - if !bb.is_terminated() { - bb.set_terminator(MirInstruction::Jump { target: merge_bb }); - } else { - term = true; - } + if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, eend, merge_bb); } + else { term = true; } } (eend, ev, term) } else { - if let Some(bb) = f.get_block_mut(else_bb) { - bb.set_terminator(MirInstruction::Jump { target: merge_bb }); - } + crate::mir::ssot::cf_common::set_jump(f, else_bb, merge_bb); (else_bb, base_vars.clone(), false) }; // If both branches terminate (e.g., both return/throw), no merge or var-join is needed. diff --git a/src/runner/json_v0_bridge/lowering/loop_.rs b/src/runner/json_v0_bridge/lowering/loop_.rs index 93b15b59..020b657c 100644 --- a/src/runner/json_v0_bridge/lowering/loop_.rs +++ b/src/runner/json_v0_bridge/lowering/loop_.rs @@ -33,9 +33,7 @@ pub(super) fn lower_loop_stmt( // 2) preheader → header へ Jump(ヘッダで Phi を組む前に制御を渡す) if let Some(bb) = f.get_block_mut(cur_bb) { - if !bb.is_terminated() { - bb.add_instruction(MirInstruction::Jump { target: cond_bb }); - } + if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, cur_bb, cond_bb); } } // 3) LoopPhiOps アダプタ(準備用: preheader seed 専用) @@ -115,13 +113,7 @@ pub(super) fn lower_loop_stmt( let header_vars_snapshot = ops.vars.clone(); let (cval, _cend) = super::expr::lower_expr_with_vars(env, ops.f, cond_bb, cond, ops.vars)?; - if let Some(bb) = ops.f.get_block_mut(cond_bb) { - bb.set_terminator(MirInstruction::Branch { - condition: cval, - then_bb: body_bb, - else_bb: exit_bb, - }); - } + crate::mir::ssot::cf_common::set_branch(ops.f, cond_bb, cval, body_bb, exit_bb); let mut body_vars = ops.vars.clone(); // open snapshot frames for nested break/continue super::push_loop_snapshot_frames(); @@ -140,9 +132,7 @@ pub(super) fn lower_loop_stmt( block_var_maps2.insert(cur_bb, base_vars.clone()); block_var_maps2.insert(bend, body_vars.clone()); if let Some(bb) = ops.f.get_block_mut(bend) { - if !bb.is_terminated() { - bb.set_terminator(MirInstruction::Jump { target: cond_bb }); - } + if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(ops.f, bend, cond_bb); } } let backedge_to_cond = matches!( ops.f.blocks diff --git a/src/runner/json_v0_bridge/lowering/match_expr.rs b/src/runner/json_v0_bridge/lowering/match_expr.rs index 1823c997..7662b34b 100644 --- a/src/runner/json_v0_bridge/lowering/match_expr.rs +++ b/src/runner/json_v0_bridge/lowering/match_expr.rs @@ -21,9 +21,7 @@ pub(super) fn lower_match_expr_with_scope( // Set up blocks let dispatch_bb = new_block(f); if let Some(bb) = f.get_block_mut(start_bb) { - if !bb.is_terminated() { - bb.set_terminator(MirInstruction::Jump { target: dispatch_bb }); - } + if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, start_bb, dispatch_bb); } } let else_bb = new_block(f); let merge_bb = new_block(f); @@ -42,16 +40,14 @@ pub(super) fn lower_match_expr_with_scope( if let Some(bb) = f.get_block_mut(cur_dispatch) { // compare scr_val == label bb.add_instruction(MirInstruction::Const { dst: ldst, value: ConstValue::String(arm.label.clone()) }); - bb.add_instruction(MirInstruction::Compare { dst: cond, op: CompareOp::Eq, lhs: scr_val, rhs: ldst }); - bb.set_terminator(MirInstruction::Branch { condition: cond, then_bb, else_bb: fall_bb }); } + crate::mir::ssot::cf_common::emit_compare_func(f, cur_dispatch, cond, CompareOp::Eq, scr_val, ldst); + crate::mir::ssot::cf_common::set_branch(f, cur_dispatch, cond, then_bb, fall_bb); // Then arm body let (tval, tend) = lower_expr_with_scope(env, f, then_bb, &arm.expr, vars)?; if let Some(bb) = f.get_block_mut(tend) { - if !bb.is_terminated() { - bb.set_terminator(MirInstruction::Jump { target: merge_bb }); - } + if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, tend, merge_bb); } } phi_inputs.push((tend, tval)); @@ -61,19 +57,14 @@ pub(super) fn lower_match_expr_with_scope( // Else body let (eval, eend) = lower_expr_with_scope(env, f, else_bb, else_expr, vars)?; if let Some(bb) = f.get_block_mut(eend) { - if !bb.is_terminated() { - bb.set_terminator(MirInstruction::Jump { target: merge_bb }); - } + if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, eend, merge_bb); } } phi_inputs.push((eend, eval)); // Merge result let out = f.next_value_id(); // フェーズM.2: PHI統一処理(no_phi分岐削除) - if let Some(bb) = f.get_block_mut(merge_bb) { - let mut inputs = phi_inputs; - inputs.sort_by_key(|(bbid, _)| bbid.0); - bb.insert_instruction_after_phis(MirInstruction::Phi { dst: out, inputs }); - } + let inputs = phi_inputs; + crate::mir::ssot::cf_common::insert_phi_at_head(f, merge_bb, out, inputs); Ok((out, merge_bb)) } diff --git a/src/runner/json_v0_bridge/lowering/merge.rs b/src/runner/json_v0_bridge/lowering/merge.rs index 9628dae0..76709d53 100644 --- a/src/runner/json_v0_bridge/lowering/merge.rs +++ b/src/runner/json_v0_bridge/lowering/merge.rs @@ -42,11 +42,13 @@ pub(super) fn merge_values( if let Some(bb) = f.get_block_mut(pred_b) { bb.add_instruction_before_terminator(MirInstruction::Copy { dst, src: val_b }); } - } else if let Some(bb) = f.get_block_mut(merge_bb) { - bb.insert_instruction_after_phis(MirInstruction::Phi { + } else { + crate::mir::ssot::cf_common::insert_phi_at_head( + f, + merge_bb, dst, - inputs: vec![(pred_a, val_a), (pred_b, val_b)], - }); + vec![(pred_a, val_a), (pred_b, val_b)], + ); } dst } @@ -97,4 +99,3 @@ pub(super) fn merge_var_maps( } } } - diff --git a/src/runner/json_v0_bridge/lowering/ternary.rs b/src/runner/json_v0_bridge/lowering/ternary.rs index 26ee13f6..c5a8212f 100644 --- a/src/runner/json_v0_bridge/lowering/ternary.rs +++ b/src/runner/json_v0_bridge/lowering/ternary.rs @@ -24,31 +24,18 @@ pub(super) fn lower_ternary_expr_with_scope( let then_bb = new_block(f); let else_bb = new_block(f); let merge_bb = new_block(f); - if let Some(bb) = f.get_block_mut(cur) { - bb.set_terminator(MirInstruction::Branch { - condition: cval, - then_bb, - else_bb, - }); - } + crate::mir::ssot::cf_common::set_branch(f, cur, cval, then_bb, else_bb); let (tval, tend) = lower_expr_with_scope(env, f, then_bb, then_e, vars)?; if let Some(bb) = f.get_block_mut(tend) { - if !bb.is_terminated() { - bb.set_terminator(MirInstruction::Jump { target: merge_bb }); - } + if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, tend, merge_bb); } } let (eval, eend) = lower_expr_with_scope(env, f, else_bb, else_e, vars)?; if let Some(bb) = f.get_block_mut(eend) { - if !bb.is_terminated() { - bb.set_terminator(MirInstruction::Jump { target: merge_bb }); - } + if !bb.is_terminated() { crate::mir::ssot::cf_common::set_jump(f, eend, merge_bb); } } let out = f.next_value_id(); // フェーズM.2: PHI統一処理(no_phi分岐削除) - if let Some(bb) = f.get_block_mut(merge_bb) { - let mut inputs = vec![(tend, tval), (eend, eval)]; - inputs.sort_by_key(|(bbid, _)| bbid.0); - bb.insert_instruction_after_phis(MirInstruction::Phi { dst: out, inputs }); - } + let mut inputs = vec![(tend, tval), (eend, eval)]; + crate::mir::ssot::cf_common::insert_phi_at_head(f, merge_bb, out, inputs); Ok((out, merge_bb)) } diff --git a/src/runner/json_v0_bridge/lowering/throw_ctx.rs b/src/runner/json_v0_bridge/lowering/throw_ctx.rs index 8d479ffa..667544d6 100644 --- a/src/runner/json_v0_bridge/lowering/throw_ctx.rs +++ b/src/runner/json_v0_bridge/lowering/throw_ctx.rs @@ -37,12 +37,7 @@ pub(super) fn record_throw(f: &mut MirFunction, from_bb: BasicBlockId, exc_val: THROW_CTX.with(|slot| { if let Some(ctx) = slot.borrow_mut().as_mut() { let target = ctx.catch_bb; - if let Some(bb) = f.get_block_mut(from_bb) { - bb.set_terminator(MirInstruction::Jump { target }); - } - if let Some(succ) = f.get_block_mut(target) { - succ.add_predecessor(from_bb); - } + crate::mir::ssot::cf_common::set_jump(f, from_bb, target); ctx.incoming.push((from_bb, exc_val)); Some(target) } else { diff --git a/src/runner/json_v0_bridge/lowering/try_catch.rs b/src/runner/json_v0_bridge/lowering/try_catch.rs index 4c255392..8dae85a3 100644 --- a/src/runner/json_v0_bridge/lowering/try_catch.rs +++ b/src/runner/json_v0_bridge/lowering/try_catch.rs @@ -69,10 +69,10 @@ pub(super) fn lower_try_stmt( // フェーズM.2: PHI統一処理(no_phi条件削除) if !incoming_exc.is_empty() { let phi_dst = f.next_value_id(); - if let Some(bb) = f.get_block_mut(catch_bb) { + if let Some(_bb) = f.get_block_mut(catch_bb) { let mut inputs = incoming_exc.clone(); inputs.sort_by_key(|(bbid, _)| bbid.0); - bb.insert_instruction_after_phis(MirInstruction::Phi { dst: phi_dst, inputs }); + crate::mir::ssot::cf_common::insert_phi_at_head(f, catch_bb, phi_dst, inputs); } catch_vars.insert(param.clone(), phi_dst); } @@ -125,8 +125,8 @@ pub(super) fn lower_try_stmt( phi_entries.push((dst, inputs)); merged_vars.insert(name.clone(), dst); } - if let Some(bb) = f.get_block_mut(finally_block) { - for (dst, inputs) in phi_entries { bb.insert_instruction_after_phis(MirInstruction::Phi { dst, inputs }); } + if let Some(_bb) = f.get_block_mut(finally_block) { + for (dst, inputs) in phi_entries { crate::mir::ssot::cf_common::insert_phi_at_head(f, finally_block, dst, inputs); } } let mut finally_vars = merged_vars.clone(); let final_end = super::lower_stmt_list_with_vars(f, finally_block, finally, &mut finally_vars, loop_stack, env)?; @@ -156,8 +156,8 @@ pub(super) fn lower_try_stmt( phi_entries.push((dst, inputs)); merged_vars.insert(name.clone(), dst); } - if let Some(bb) = f.get_block_mut(exit_bb) { - for (dst, inputs) in phi_entries { bb.insert_instruction_after_phis(MirInstruction::Phi { dst, inputs }); } + if let Some(_bb) = f.get_block_mut(exit_bb) { + for (dst, inputs) in phi_entries { crate::mir::ssot::cf_common::insert_phi_at_head(f, exit_bb, dst, inputs); } } *vars = merged_vars; return Ok(exit_bb); @@ -259,10 +259,8 @@ pub(super) fn lower_try_stmt( merged_vars.insert(name.clone(), dst); } // フェーズM.2: PHI統一処理(no_phi分岐削除) - if let Some(bb) = f.get_block_mut(finally_block) { - for (dst, inputs) in phi_entries { - bb.insert_instruction_after_phis(MirInstruction::Phi { dst, inputs }); - } + if let Some(_bb) = f.get_block_mut(finally_block) { + for (dst, inputs) in phi_entries { crate::mir::ssot::cf_common::insert_phi_at_head(f, finally_block, dst, inputs); } } let mut finally_vars = merged_vars.clone(); let final_end = lower_stmt_list_with_vars( @@ -310,10 +308,8 @@ pub(super) fn lower_try_stmt( merged_vars.insert(name.clone(), dst); } // フェーズM.2: PHI統一処理(no_phi分岐削除) - if let Some(bb) = f.get_block_mut(exit_bb) { - for (dst, inputs) in phi_entries { - bb.insert_instruction_after_phis(MirInstruction::Phi { dst, inputs }); - } + if let Some(_bb) = f.get_block_mut(exit_bb) { + for (dst, inputs) in phi_entries { crate::mir::ssot::cf_common::insert_phi_at_head(f, exit_bb, dst, inputs); } } *vars = merged_vars; Ok(exit_bb) diff --git a/tools/smokes/v2/profiles/quick/core/phase2039/mirbuilder_match_core_exec_canary_vm.sh b/tools/smokes/v2/profiles/quick/core/phase2039/mirbuilder_match_core_exec_canary_vm.sh new file mode 100644 index 00000000..f9fb1c5c --- /dev/null +++ b/tools/smokes/v2/profiles/quick/core/phase2039/mirbuilder_match_core_exec_canary_vm.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# Match lowering via JSON v0 bridge (SSOT cf_common) → expect rc=2 +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"; if ROOT_GIT=$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null); then ROOT="$ROOT_GIT"; else ROOT="$(cd "$SCRIPT_DIR/../../../../../../../../.." && pwd)"; fi +source "$ROOT/tools/smokes/v2/lib/test_runner.sh"; require_env || exit 2 + +tmp_json="/tmp/program_match_$$.json" +cat > "$tmp_json" <<'JSON' +{ + "version": 0, + "kind": "Program", + "body": [ + { "type":"Local", "name":"s", "expr": {"type":"Str","value":"b"} }, + { "type":"Local", "name":"x", "expr": {"type":"Match","scrutinee":{"type":"Var","name":"s"}, + "arms":[ + {"label":"a","expr":{"type":"Int","value":1}}, + {"label":"b","expr":{"type":"Int","value":2}} + ], + "else":{"type":"Int","value":9} + } }, + { "type":"Return", "expr": {"type":"Var","name":"x"} } + ] +} +JSON + +set +e +HAKO_VERIFY_PRIMARY=core verify_mir_rc "$tmp_json" >/dev/null 2>&1 +rc=$? +set -e +rm -f "$tmp_json" || true + +if [ "$rc" -eq 2 ]; then + echo "[PASS] mirbuilder_match_core_exec_canary_vm" + exit 0 +fi +echo "[FAIL] mirbuilder_match_core_exec_canary_vm (rc=$rc, expect 2)" >&2; exit 1 + diff --git a/tools/smokes/v2/profiles/quick/core/phase2039/mirbuilder_ternary_core_exec_canary_vm.sh b/tools/smokes/v2/profiles/quick/core/phase2039/mirbuilder_ternary_core_exec_canary_vm.sh new file mode 100644 index 00000000..91bb9ddb --- /dev/null +++ b/tools/smokes/v2/profiles/quick/core/phase2039/mirbuilder_ternary_core_exec_canary_vm.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Ternary lowering via JSON v0 bridge (SSOT cf_common) → expect rc=1 +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"; if ROOT_GIT=$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null); then ROOT="$ROOT_GIT"; else ROOT="$(cd "$SCRIPT_DIR/../../../../../../../../.." && pwd)"; fi +source "$ROOT/tools/smokes/v2/lib/test_runner.sh"; require_env || exit 2 + +tmp_json="/tmp/program_ternary_$$.json" +cat > "$tmp_json" <<'JSON' +{ + "version": 0, + "kind": "Program", + "body": [ + { "type":"Local", "name":"c", "expr": {"type":"Bool","value":true} }, + { "type":"Local", "name":"x", "expr": {"type":"Ternary", "cond":{"type":"Var","name":"c"}, "then":{"type":"Int","value":1}, "else":{"type":"Int","value":2}} }, + { "type":"Return", "expr": {"type":"Var","name":"x"} } + ] +} +JSON + +set +e +HAKO_VERIFY_PRIMARY=core verify_mir_rc "$tmp_json" >/dev/null 2>&1 +rc=$? +set -e +rm -f "$tmp_json" || true + +if [ "$rc" -eq 1 ]; then + echo "[PASS] mirbuilder_ternary_core_exec_canary_vm" + exit 0 +fi +echo "[FAIL] mirbuilder_ternary_core_exec_canary_vm (rc=$rc, expect 1)" >&2; exit 1 +