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