feat(joinir): Phase 257 P1.1/P1.2/P1.3 - Pattern6 SSOT + LoopHeaderPhi CFG fix

P1.1: Pattern6 false positive fix (SSOT approach)
- can_lower() now calls extract_scan_with_init_parts() for SSOT
- index_of_string/2 no longer triggers false positive
- Graceful fall-through with Ok(None)

P1.2: LoopHeaderPhi CFG-based correction
- Step 0: Manual successor update from terminators
- CFG-based entry predecessor computation (header_preds - latch)
- Multi-entry-pred support (bb0 host + bb10 JoinIR main)
- Explicit host_entry_block addition (emit_jump runs after finalize)

P1.3: Smoke script validation
- phase254_p0_index_of_vm.sh: --verify + VM error detection
- phase257 smokes updated

Acceptance criteria (all PASS):
 phase254_p0_index_of_min.hako verify
 phase257_p0_last_index_of_min.hako verify
 ./tools/smokes/v2/run.sh --profile quick (no Pattern6 false positive)

Technical discovery:
- Host entry block (bb0) Jump set in Phase 6 (after finalize)
- instruction_rewriter bypasses set_terminator(), skips successor update

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-20 23:30:27 +09:00
parent 9ba89bada2
commit 73ddc5f58d
10 changed files with 492 additions and 71 deletions

View File

@ -8,9 +8,9 @@ Related:
## Current Status (SSOT)
- Target first FAIL: `json_lint_vm / StringUtils.last_index_of/2`
- Pattern: Loop with early return (backward scan)
- Approach: Extend Pattern6ScanWithInitto support reverse scan + early return
- Former first FAIL: `json_lint_vm / StringUtils.last_index_of/2`P0/P1で解消
- Current first FAIL: `json_lint_vm / StringUtils.is_integer/1`nested-if + loop, still unsupported
- Approach (done): Pattern6ScanWithInit reverse scan + early return に拡張し、PHI/CFG を fail-fast + 自動補正で安定化
---
@ -120,6 +120,60 @@ Pattern6ScanWithInitを “scan direction” を持つ形に一般化す
- Phase 256 系の契約(`JumpArgsLayout` / contract checksに従い、推測しない
- `expr_result``return i` の経路でのみ使用not-found は `-1`
---
## Progress
### P0完了
- Pattern6 を双方向 scan に拡張forward/reverse
- reverse scan 用 lowerer を追加(`scan_with_init_reverse.rs`
- `apps/tests/phase257_p0_last_index_of_min.hako` を追加
- ただし現状は「PHI predecessor mismatch」が先に露出しており、P1 でインフラ不変条件を固定する必要がある
## Phase 257 P1次の指示書 / SSOT
### Goal
- Pattern6 の実行時 `phi pred mismatch` を根治し、`index_of` / `last_index_of` が VM で正常に走る
- `./tools/smokes/v2/run.sh --profile quick` の最初の FAIL を次へ進める
### Tasks順序
1) MIR verifier を強化して `InvalidPhi` を検出するfail-fast
- 期待: phi inputs が「ブロックの predecessor 全部」をカバーし、自己ブロックselfを含まない
2) Pattern6 の loop header PHI の entry edge source を正す
- `entry_block == header_block` になっているケースを禁止し、必要なら preheader を作る or merge entry を main に寄せる
3) smoke の false positive を防ぐ
- `phase254_p0_index_of_vm.sh``--verify` を併用するか、VM error を検出して FAIL にする
---
## Progress
### P0完了
- Pattern6 を双方向 scan に拡張forward/reverse
- reverse scan 用 lowerer を追加
- fixture: `apps/tests/phase257_p0_last_index_of_min.hako`
### P1完了
- Pattern6 の誤検出を防止detect/extract SSOT 化)
- `index_of_string/2` など “近いが別形” を `Ok(None)` で fall-through させる
- MIR verifier に PHI predecessor 検証を追加fail-fast
- unreachable pred は除外して現実的に運用
- loop header PHI の entry edge を CFG から復元self pred 根治)
- merge 内で `terminator` 直書きにより `successors` が同期されないケースを補正
- finalize 時点で host entry jump が未設定なため、host entry predecessor を明示的に補う
- smoke の false positive を抑止(`--verify` + VM error 検出)
## Next (Phase 258 proposal)
- `StringUtils.is_integer/1` の loop を JoinIR で受理するcaps=If,Loop,NestedIf,Return
- ループ形: `loop(i < s.length()) { if not is_digit(...) return false; i=i+1 } return true`
- 前処理に nested-if がある(`start` の決定)
**Option B: Pattern8_ReverseScanReturn 新設**
Pattern6 を触らずに、reverse scan 専用パターンとして箱を追加する。