From cf4d98ed08369cf314c38d83db7267381b674e3b Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Sun, 14 Dec 2025 08:02:23 +0900 Subject: [PATCH] =?UTF-8?q?fix(llvm):=20Phase=20131-8=20-=20ExternCall=20a?= =?UTF-8?q?rgument=20handling=20=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 131-8: ExternCall が PHI 値を正しく受け取るように修正 問題: - ExternCall が resolve_ptr() を使用 - PHI 値は local vmap にない → null を返す - 結果: console.log が常に 0 を出力 修正: - src/llvm_py/instructions/externcall.py: - resolve_ptr() → resolve_i64_strict() に統一 - 他の命令(binop, compare, copy)と同じ resolver を使用 テスト結果: - Before: 0,0,0 - After: 0,01,011 (PHI 値が正しく渡る!) - Case A: ✅ 退行なし (exit code 42) 新規発見(スコープ外): - MIR 型推論バグ: %3 が String 型として扱われる - 出力が 0,1,2 ではなく 0,01,011(文字列連結) - → Rust frontend の問題(Phase 131-9 候補) 箱化モジュール化: - ✅ resolve_i64_strict() に統一 - ✅ Value resolution vs Type conversion の責務分離 - ✅ 構造的解決 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/llvm_py/instructions/externcall.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/llvm_py/instructions/externcall.py b/src/llvm_py/instructions/externcall.py index 904c9ea3..168c1180 100644 --- a/src/llvm_py/instructions/externcall.py +++ b/src/llvm_py/instructions/externcall.py @@ -7,6 +7,7 @@ import llvmlite.ir as ir from typing import Dict, List, Optional, Any from instructions.safepoint import insert_automatic_safepoint from instructions.extern_normalize import normalize_extern_name +from utils.values import resolve_i64_strict def lower_externcall( builder: ir.IRBuilder, @@ -103,20 +104,19 @@ def lower_externcall( call_args: List[ir.Value] = [] for i, arg_id in enumerate(args): orig_arg_id = arg_id - # Prefer resolver/ctx + # ALWAYS resolve as i64 first (handles PHI values correctly) + # Type coercion to pointer happens below if needed aval = None if resolver is not None and preds is not None and block_end_values is not None and bb_map is not None: try: - if len(func.args) > i and isinstance(func.args[i].type, ir.PointerType): - aval = resolver.resolve_ptr(arg_id, builder.block, preds, block_end_values, vmap) - else: - aval = resolver.resolve_i64(arg_id, builder.block, preds, block_end_values, vmap, bb_map) + # Use strict resolver (handles PHI values correctly, same as binop/compare/copy) + aval = resolve_i64_strict(resolver, arg_id, builder.block, preds, block_end_values, vmap, bb_map) except Exception: aval = None if aval is None: aval = vmap.get(arg_id) if aval is None: - # Default guess + # Fallback (should rarely hit with resolve_i64_strict) aval = ir.Constant(i64, 0) # If function prototype is known, coerce to expected type