feat(joinir): Phase 33-7 IfMerge lowering for multiple-variable PHI

Implements IfMerge instruction lowering to support multiple variables
merging from if/else branches (Phase 33-7: return pattern only).

## Changes

- Add src/mir/join_ir/lowering/if_merge.rs (232 lines)
  - IfMergeLowerer with pattern matching for common variables
  - extract_written_vars() / find_written_value() helpers
  - Phase 33-7 constraint: return pattern only (k_next=None)

- Update src/mir/join_ir/lowering/mod.rs
  - Unified entry point: try_lower_if_to_joinir()
  - Priority: IfMerge → Select → if_phi fallback
  - Add IfMergeTest.* to whitelist

- Add unit tests in src/tests/mir_joinir_if_select.rs
  - test_if_merge_simple_pattern (2 variables)
  - test_if_merge_multiple_pattern (3 variables)
  - All 7/7 tests PASS 

- Add reference test cases
  - apps/tests/joinir_if_merge_simple.hako (2-var pattern)
  - apps/tests/joinir_if_merge_multiple.hako (3-var pattern)

## Test Results

 Simple pattern (2 vars): merges=2, k_next=None
 Multiple pattern (3 vars): merges=3, k_next=None
 test result: ok. 7 passed; 0 failed

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-27 08:18:09 +09:00
parent 2d379692e3
commit 5b7818f5c9
5 changed files with 602 additions and 9 deletions

View File

@ -0,0 +1,73 @@
// Phase 33-7: IfMerge lowering test (multiple variables pattern)
//
// Pattern: if cond { x=a; y=b; z=c } else { x=d; y=e; z=f } return x+y+z
// Expected:
// - cond=true → (x=10, y=20, z=30) → return 60
// - cond=false → (x=40, y=50, z=60) → return 150
static box IfMergeTest {
multiple_true() {
local x
local y
local z
if true {
x = 10
y = 20
z = 30
} else {
x = 40
y = 50
z = 60
}
return x + y + z
}
multiple_false() {
local x
local y
local z
if false {
x = 10
y = 20
z = 30
} else {
x = 40
y = 50
z = 60
}
return x + y + z
}
main() {
local result_true
local result_false
result_true = me.multiple_true()
result_false = me.multiple_false()
print("multiple_true: ")
print(result_true)
print("\n")
print("multiple_false: ")
print(result_false)
print("\n")
// Verify results
if result_true == 60 {
print("PASS: multiple_true\n")
} else {
print("FAIL: multiple_true\n")
}
if result_false == 150 {
print("PASS: multiple_false\n")
} else {
print("FAIL: multiple_false\n")
}
}
}

View File

@ -0,0 +1,67 @@
// Phase 33-7: IfMerge lowering test (simple pattern)
//
// Pattern: if cond { x=a; y=b } else { x=c; y=d } return x+y
// Expected:
// - cond=true → (x=1, y=2) → return 3
// - cond=false → (x=3, y=4) → return 7
static box IfMergeTest {
simple_true() {
local x
local y
if true {
x = 1
y = 2
} else {
x = 3
y = 4
}
return x + y
}
simple_false() {
local x
local y
if false {
x = 1
y = 2
} else {
x = 3
y = 4
}
return x + y
}
main() {
local result_true
local result_false
result_true = me.simple_true()
result_false = me.simple_false()
print("simple_true: ")
print(result_true)
print("\n")
print("simple_false: ")
print(result_false)
print("\n")
// Verify results
if result_true == 3 {
print("PASS: simple_true\n")
} else {
print("FAIL: simple_true\n")
}
if result_false == 7 {
print("PASS: simple_false\n")
} else {
print("FAIL: simple_false\n")
}
}
}