Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

uint64 literals generate suboptimal IL code #8683

Closed
teo-tsirpanis opened this issue Mar 7, 2020 · 5 comments · Fixed by #8692
Closed

uint64 literals generate suboptimal IL code #8683

teo-tsirpanis opened this issue Mar 7, 2020 · 5 comments · Fixed by #8692

Comments

@teo-tsirpanis
Copy link
Contributor

Repro steps

Consider this function:

let inc x = x + 1UL

Now look at the generated IL code:

Expected behavior

IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: conv.u8
IL_0003: add
IL_0004: ret

This is what C# generates. Generally, it should emit ldc.i4.#/ldc.i4.s/ldc.i4 with a conv, and only if the number is even bigger should it emit ldc.i8.

Actual behavior

IL_0000: ldarg.0
IL_0001: ldc.i8 1
IL_000a: add
IL_000b: ret

The function's IL code takes 12 bytes, instead of 5, as expected. This might interfere with the JIT's decision to inline small functions.

Known workarounds

let inc x = x + (uint64 1)

Related information

This happens only with uint64 literals. Literals of all other integral types (including signed int64) emit optimal code.

@cartermp
Copy link
Contributor

cartermp commented Mar 8, 2020

@teo-tsirpanis
Copy link
Contributor Author

I know about the JITted code being identical. The problem is that F#'s IL code is not as compact as it is with C#. And as I said before, it might affect how the JIT performs inlining.

@cartermp
Copy link
Contributor

cartermp commented Mar 9, 2020

Compactness of IL isn't necessarily a problem, which is also why optimization is difficult here. If the JIT optimizes it all the same, we'd need some evidence that this affects JIT inlining to say it's really a problem. As it stands, I think the best rationale for making a change here is consistency with C#.

@teo-tsirpanis
Copy link
Contributor Author

I agree. What source files are responsible for that? I want to try to fix it myself.

@cartermp
Copy link
Contributor

Awesome! A good place to start would probably be in ILXGen, perhaps here: https://github.com/dotnet/fsharp/blob/master/src/fsharp/IlxGen.fs#L2433

Typically ILXGen is where the "translate F# to IL" happens, though some lower-level stuff can occur elsewhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants