Phase 116 固定: if-only で片側が元値保持、片側が call 結果の merge パターン ## 実装内容 ### Fixture - `apps/tests/phase116_if_only_keep_plus_call_min.hako` - Expected output: `10\n2` - Pattern: - then側: call結果でvを更新 (`v = f(1)`) - else側: 元の値を保持 (`v = 10`) - merge地点: 異なるソース(元値 vs call結果)からのPHI ### Smoke Tests - `phase116_if_only_keep_plus_call_vm.sh` - VM parity - output_validator.sh で数値2行 `10\n2` を検証 - `NYASH_DISABLE_PLUGINS=1 HAKO_JOINIR_STRICT=1` - `phase116_if_only_keep_plus_call_llvm_exe.sh` - LLVM EXE parity - llvm_exe_runner.sh を利用(plugin dlopen/cache/build-all SSOT) - llvm_exe_build_and_run_numeric_smoke で検証 ## 検証結果 ✅ VM smoke: PASS (10\n2) ✅ LLVM EXE smoke: PASS (10\n2) ✅ 回帰 (Phase 115): PASS (2\n3) ## 技術的詳細 ### JoinIR Pattern 1 (Simple If) ``` entry_block: v = 10 if flag == 1 goto then_block else exit_block then_block: v = f(1) goto exit_block exit_block: v_merged = PHI [v=10 from entry, v=f(1) from then] print(v_merged) ``` ### PHI接続の重要性 - entry → exit: 元値 (`10`) を直接伝播 - then → exit: call結果 (`f(1)`) を伝播 - PHI: 異なる型のソース(変数 vs call結果)を正しくmerge LLVM IRでは、これらが適切な型で統一される必要がある。 ## Box-First原則の適用 ✅ 既存の箱化されたコンポーネントを活用 - output_validator.sh による出力検証の統一 - llvm_exe_runner.sh によるLLVM実行の標準化 - テストインフラの再利用(no reinvention) ## Fail-Fast原則 ✅ VM/LLVM両方でエラーを即座に検出 - `HAKO_JOINIR_STRICT=1` で厳密な検証 - フォールバック処理なし(エラーは明示的に失敗) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Smokes v2 — Minimal Runner and Policy
Policy
- Use [SKIP:] prefix for environment/host dependent skips.
- Examples: [SKIP] hakorune not built, [SKIP:env] plugin path missing
- Keep reasons short and stable to allow grep-based canaries.
- Prefer JSON-only output in CI: set
NYASH_JSON_ONLY=1to avoid noisy logs. - Diagnostics lines like
[provider/select:*]are filtered by default inlib/test_runner.sh.- Toggle: set
HAKO_SILENT_TAGS=0to disable filtering and show raw logs.HAKO_SHOW_CALL_LOGS=1also bypasses filtering.
- Toggle: set
Helpers
tools/smokes/v2/lib/mir_canary.shprovides:extract_mir_from_output— between [MIR_BEGIN]/[MIR_END]assert_has_tokens,assert_skip_tag,assert_order,assert_token_count
tools/lib/canary.shprovides minimal, harness-agnostic aliases:extract_mir_between_tags— same asextract_mir_from_outputrequire_tokens token...— fail if any token missing
Notes
- Avoid running heavy integration smokes in CI by default. Use
--profile quick. - When a test depends on external tools (e.g., LLVM), prefer
[SKIP:<reason>]over failure. - Stage‑B/selfhost canaries(
stage1_launcher_*,phase251*など)は Stage‑3 デフォルト環境で安定しないため、quick プロファイルでは[SKIP:stageb]として扱い、必要に応じて別プロファイル(integration/full)で個別に実行する。 - Selfhost quick カバレッジは最小 1 本(
core/selfhost_minimal.sh)に絞り、Stage‑3 + JoinIR 前提で Stage‑B→VM を通るかだけを確認する。 - S3 backend 向けの長尺テスト群も quick 向きではないため、timeout を短く保ちたい場合は
[SKIP:slow]にして別途ローカルで回すことを推奨する。
Quick tips
- EXE-heavy cases (e.g.,
phase2100/*) may take longer. When running quick with these tests, pass a larger timeout like--timeout 120. - Smokes v2 auto-cleans temporary crate EXE objects created under
/tmp(pattern:ny_crate_backend_exe_*.o) after the run.
Developer Notes
- JoinIR If/Select (Phase 33): A/B test with
NYASH_FEATURES=stage3 HAKO_JOINIR_IF_SELECT=1 ./target/release/hakorune apps/tests/joinir_if_select_simple.hako(dev-only、CI対象外。NYASH_JOINIR_CORE は deprecated/無視)