Phase 115実装 - if分岐内での関数呼び出し結果をマージするパターンを固定 **実装内容**: - Fixture: phase115_if_only_call_merge_min.hako (expected: 2, 3) - if/else両分岐で関数呼び出し f() の結果を変数 v に代入 - if後にマージされた v を使用(LLVM EXE でのPHI node生成を検証) - VM smoke: phase115_if_only_call_merge_vm.sh - NYASH_DISABLE_PLUGINS=1 HAKO_JOINIR_STRICT=1 で実行 - LLVM EXE smoke: phase115_if_only_call_merge_llvm_exe.sh - llvm_exe_runner.sh を利用した標準パリティ検証 **検証結果**: - VM test: PASS ✅ - LLVM EXE test: PASS ✅ - Phase 114 regression: PASS ✅ **箱化モジュール化の観点**: - 単一責任: 各smokeは1パターンのみ検証(call result merge) - 分離: VM/LLVM EXEで独立したテスト(llvm_exe_runner.sh経由) - Fail-Fast: HAKO_JOINIR_STRICT=1 で不正な制御フローを即座に検出 **関連**: - Phase 103: If-Only基本パリティ(制御フロー基礎) - Phase 113: If-Only部分代入パリティ(変数マージ) - Phase 114: If-Only return+post パリティ(early returnとpost-if文) - Phase 115: If-Only call result merge パリティ(関数呼び出し結果マージ) ← 今回 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 115: If-Only Call Result Merge Parity
Status: ✅ DONE Date: 2025-12-18
背景
LLVMバックエンドで壊れやすいパターン - if分岐内での関数呼び出し結果をマージするケース。
問題パターン
fn f(x) { return x + 1 }
fn g(flag) {
local v = 0
if flag == 1 { v = f(1) } else { v = f(2) }
print(v)
}
このパターンでは:
- if/else両分岐で関数呼び出し
f()が発生 - その結果を変数
vに代入 - if後にマージされた
vを使用
LLVM EXEモードでは、PHI node生成やSSA変換が正しく行われない可能性がある。
実装内容
1. テストフィクスチャ
- ファイル:
/home/tomoaki/git/hakorune-selfhost/apps/tests/phase115_if_only_call_merge_min.hako - 期待出力:
2\n3g(1)→f(1)→1+1→2g(0)→f(2)→2+1→3
2. VM Smoke Test
- ファイル:
/home/tomoaki/git/hakorune-selfhost/tools/smokes/v2/profiles/integration/apps/phase115_if_only_call_merge_vm.sh - 環境変数:
NYASH_DISABLE_PLUGINS=1 HAKO_JOINIR_STRICT=1 - 検証: 数値行抽出して
2\n3と比較
3. LLVM EXE Smoke Test
- ファイル:
/home/tomoaki/git/hakorune-selfhost/tools/smokes/v2/profiles/integration/apps/phase115_if_only_call_merge_llvm_exe.sh - 利用:
tools/smokes/v2/lib/llvm_exe_runner.sh - 検証:
EXPECTED='2\n3',EXPECTED_LINES=2
検証コマンド
# VM smoke test
bash tools/smokes/v2/profiles/integration/apps/phase115_if_only_call_merge_vm.sh
# LLVM EXE smoke test
bash tools/smokes/v2/profiles/integration/apps/phase115_if_only_call_merge_llvm_exe.sh
# Phase 114回帰テスト(推奨)
bash tools/smokes/v2/profiles/integration/apps/phase114_if_only_return_then_post_llvm_exe.sh
関連Phase
- Phase 103: If-Only基本パリティ(制御フロー基礎)
- Phase 113: If-Only部分代入パリティ(変数マージ)
- Phase 114: If-Only return+post パリティ(early returnとpost-if文)
- Phase 115: If-Only call result merge パリティ(関数呼び出し結果マージ) ← 今回
技術的詳細
JoinIR → MIR変換
If-Only Pattern 1では:
- Then/Else分岐それぞれで関数呼び出し
- 各分岐の終端で変数への代入
- Exit block入口でPHI node生成(then_value vs else_value)
- Post-if文でマージされた値を使用
LLVM SSA変換
LLVM EXEモードでは:
- 関数呼び出し結果を一時レジスタに保持
- 各分岐終端でstore
- Exit block入口でload + phi
- Post-if文でphi結果を使用
Fail-Fast原則
- プラグイン無効化(
NYASH_DISABLE_PLUGINS=1)でコア機能のみテスト - JoinIR厳格モード(
HAKO_JOINIR_STRICT=1)で不正な制御フローを即座に検出 - 数値行のみ抽出して検証(余計なログを排除)