[IL Emit] Impove string null check il codegen
- Dominant language
- F#
- Stars
- 4.3k
- Forks
- 876
- Avg merge
- 4d 11h
- Merged PRs (30d)
- 131
Description
Consider those 2 methods:
``` fsharp
let test() =
while Console.ReadLine() <> null do
Console.WriteLine(1)
```
``` csharp
static void Test()
{
while (Console.ReadLine() != null)
Console.WriteLine(1);
}
```
If we compare outputs of F# and C# compilers in IL we can see that C# does a simple nullpointer check while F# calls to String.Equals method
F# version:
``` il
// loop start
IL_0000: call string [System.Console]System.Console::ReadLine()
IL_0005: ldnull
IL_0006: call bool [netstandard]System.String::Equals(string, string)
IL_000b: brtrue.s IL_0015 // F# is emitting a String.Equals call which then will be cut by jit in runtime but it increases dll size nonetheless
IL_000d: ldc.i4.1
IL_000e: call void [System.Console]System.Console::WriteLine(int32)
IL_0013: br.s IL_0000
// end loop
IL_0015: ret
```
C# version:
``` il
// sequence point: hidden
IL_0000: br.s IL_0008
// loop start (head: IL_0008)
IL_0002: ldc.i4.1
IL_0003: call void [System.Console]System.Console::WriteLine(int32)
IL_0008: call string [System.Console]System.Console::ReadLine()
IL_000d: brtrue.s IL_0002 // C# is emitting a simply nullpointer check here
// end loop
IL_000f: ret
```
Note that C# on top of this reverses condition and useful work resulting in better jit codegen. Coincidentally this is even more simplified repro for (https://github.com/dotnet/fsharp/issues/12138).
Contributor guide
Assessment
This issue has not been assessed yet.