Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 11, 2025

Tail calls were still emitted when pinning locals (e.g., fixed &value), leading to corrupted results at runtime.

  • Regression test: Added TailCall 08 component test covering pinned locals to ensure correct output.

Example:

[<MethodImpl(MethodImplOptions.NoInlining)>]
let foo() =
    let mutable value = 42
    use ptr = fixed &value
    bar ptr                 // should print 42 without tailcall
Original prompt

This section details on the original issue you should resolve

<issue_title>Tail calls with pinned locals</issue_title>
<issue_description>Opening another issue, since the original is closed and I haven't gotten a response there.

The original problem with pinned arrays seems to be fixed, the tail call is gone when using the newest SDK. However, there are still problems when pinning a local variable:

Repro steps

open Microsoft.FSharp.NativeInterop
open System.Runtime.CompilerServices

module Program =

    [<MethodImpl(MethodImplOptions.NoInlining)>]
    let bar (pValue: nativeptr<int>) : unit =
        let value = NativePtr.read pValue
        printfn "value = %A" value

    [<MethodImpl(MethodImplOptions.NoInlining)>]
    let foo() =
        let mutable value = 42
        use ptr = fixed &value
        bar ptr

    [<EntryPoint>]
    let main argv =
        foo()
        0

The same also happens when using the taking the address directly with the && operator:

    [<MethodImpl(MethodImplOptions.NoInlining)>]
    let foo() =
        let mutable value = 42
        bar &&value

Expected behavior

Should print 42.

Actual behavior

Tail call gets emitted and prints garbage:

 IL_0003: ldloca.s     'value'
 IL_0005: stloc.1      // V_1
 IL_0006: ldloca.s     'value'
 IL_0008: conv.i
 IL_0009: tail.
 IL_000b: call         void Program/Program::bar(int32*)
 IL_0010: ret

Known workarounds

Wrap the bar call in a try finally block.

Related information

  • .NET SDK 10.0.101</issue_description>

<agent_instructions>Locate the changes done at #18893 .
Add the newly reported test cases to it.

Execute them (not just type check, but real tests that do compile as well run in the test framework).

Include the test case with the && operator - I do not see it as mandatory change though, this operator should not be used in my opinion.

Prepare changes needed to Ilxgen for preventing a tail call emission.
Keep a TODO list and list all attempts you tried, make sure to push that TODO list as part of you work.

If you encounter any behavior, write down HYPOTHESIS.md with what you think is happening - there can be more of those. For each, add necessary instrumentation in the code and track verified/rejected in the HYPOTHESIS.md file.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

Custom agent used: F# agent
Generic agent for F# coding following the coding guidelines of F# from MsLearn


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Fix issues with tail calls and pinned locals Prevent tailcalls when locals are pinned or address-taken; add regression coverage Dec 11, 2025
Copilot AI requested a review from T-Gro December 11, 2025 12:41
@T-Gro
Copy link
Member

T-Gro commented Dec 11, 2025

/run test-baseline EmittedIL

@github-actions
Copy link
Contributor

github-actions bot commented Dec 11, 2025

✅ No release notes required

@github-actions
Copy link
Contributor

🔧 CLI Command Report

  • Command: /run test-baseline
  • Outcome: success

✅ Patch applied:
- Files changed: 2
- Lines changed: 240

Copilot AI changed the title Prevent tailcalls when locals are pinned or address-taken; add regression coverage Prevent tailcalls when pinning locals; add regression coverage Dec 12, 2025
Copilot AI requested a review from T-Gro December 12, 2025 09:19
@T-Gro
Copy link
Member

T-Gro commented Dec 15, 2025

/run test-baseline EmittedIL

@github-actions
Copy link
Contributor

🔧 CLI Command Report

  • Command: /run test-baseline
  • Outcome: success

✅ Patch applied:
- Files changed: 2
- Lines changed: 64

@T-Gro T-Gro marked this pull request as ready for review December 15, 2025 16:59
@T-Gro T-Gro requested a review from a team as a code owner December 15, 2025 16:59
@T-Gro T-Gro enabled auto-merge (squash) December 16, 2025 08:34
@github-project-automation github-project-automation bot moved this from New to In Progress in F# Compiler and Tooling Dec 16, 2025
@T-Gro T-Gro merged commit efe3c9d into main Dec 16, 2025
39 checks passed
@T-Gro T-Gro deleted the copilot/fix-tail-calls-pinned-locals branch December 16, 2025 09:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Tail calls with pinned locals

4 participants