Skip to content

Conversation

Copy link

Copilot AI commented Nov 10, 2025

LLVM's llvm.instrprof.value.profile intrinsic with IPVK_IndirectCallTarget expects function pointer addresses, not WebAssembly function indices. The code was passing zero-extended function indices (0, 1, 2, ...), causing profiles to show [0, , count] for all indirect call targets instead of distinct addresses.

Changes

core/iwasm/compilation/aot_emit_function.c (lines 2772-2793)

  • Changed from LLVMBuildZExt(func_idx, I64_TYPE) to LLVMBuildPtrToInt(func_ptr, I64_TYPE)
  • Pass function pointer value to profiling intrinsic instead of function index
// Before: recorded function index (0, 1, 2, ...)
LLVMValueRef func_idx_i64 = LLVMBuildZExt(comp_ctx->builder, func_idx, I64_TYPE, ...);
aot_call_llvm_intrinsic(..., func_idx_i64, ...);

// After: record actual function pointer address
LLVMValueRef func_ptr_i64 = LLVMBuildPtrToInt(comp_ctx->builder, func_ptr, I64_TYPE, ...);
aot_call_llvm_intrinsic(..., func_ptr_i64, ...);

This allows LLVM's PGO to correlate runtime targets with compiled functions for indirect call devirtualization and hot-path inlining.

Original prompt

Goal: Be able to use the llvm.instrprof.value.profile intrinsic to record the target function index for a call_indirect in the generated profile, like we already include counters for branches.

Problem: We do emit value profiles, but not with the correct function index values. Values in the profile are always zero!

Output:

<...>
  77_59:     Hash: 0x0000000000000040     Counters: 1     Indirect Call Site Count: 1     Indirect Target Results:         [  0, ,          1 ] (100.00%) 
<...>
  Value sites histogram:         NumTargets, SiteCount         1, 6 

TODO: fix the problem, so that the function index is properly included in the value profile.

TITLE: Fixing LLVM Value Profile Function Index Recording for WebAssembly call_indirect

USER INTENT

Fix the issue where llvm.instrprof.value.profile intrinsic is recording zero values instead of the correct function index values for call_indirect instructions in WebAssembly profiles.

TASK DESCRIPTION

The goal is to properly record target function indices for WebAssembly call_indirect instructions using LLVM's value profiling infrastructure. Currently, value profiles are being emitted but always show zero instead of actual function index values. The user wants to capture which functions are being called at indirect call sites (similar to how branch counters are already collected) to enable profile-guided optimization.

EXISTING

  • Value profiling instrumentation is already being emitted for call_indirect instructions
  • The profile data structure correctly shows indirect call site counts
  • Profile output shows entries like [0, , 1] (100.00%) indicating one call but with index 0
  • The instrumentation pass is inserting llvm.instrprof.value.profile intrinsics
  • Counter instrumentation for branches is working correctly

PENDING

  • Identify why function index values are always zero in the profile
  • Determine the correct source for function index values in WebAssembly
  • Fix the value being passed to the llvm.instrprof.value.profile intrinsic
  • Verify that the corrected values appear properly in the profile output
  • Ensure the function indices recorded are meaningful and can be used for optimization

CODE STATE

No specific files or code snippets were provided in the conversation, but the issue involves:

  • WebAssembly call_indirect instruction handling
  • LLVM instrumentation pass that inserts value profiling intrinsics
  • Profile data reading/writing infrastructure
  • The llvm.instrprof.value.profile intrinsic usage

RELEVANT CODE/DOCUMENTATION SNIPPETS

Profile output showing the problem:

77_59:     Hash: 0x0000000000000040     Counters: 1     Indirect Call Site Count: 1     Indirect Target Results:         [  0, ,          1 ] (100.00%) 

Value sites histogram:

Value sites histogram:         NumTargets, SiteCount         1, 6

OTHER NOTES

  • The issue is specific to WebAssembly's call_indirect mechanism
  • The instrumentation framework appears to be working (sites are detected, counts are recorded)
  • The problem is specifically with the value being recorded (function index), not the infrastructure itself
  • The expected behavior is to see actual function indices (non-zero values) corresponding to the called functions
  • This is likely an issue in how the function index operand is being extracted from the call_indirect instruction or how it's being passed to the profiling intrinsic

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI self-assigned this Nov 10, 2025
Copilot AI changed the title [WIP] Fix LLVM value profile function index recording for call_indirect Fix value profiling to record function pointer addresses instead of indices Nov 10, 2025
Copilot AI requested a review from Lukasdoe November 10, 2025 09:01
Copilot finished work on behalf of Lukasdoe November 10, 2025 09:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants