Search code examples
c#cil

Simple Add method produces too much IL code


I'm trying to improve my C# math operations by using IL code. One problem is currently that C# does not allow math operations on generics, but the IL does - at least for the primitive data types (interestingly not decimal). For that reason I created some test method in C# to check that the resulting IL code. Here's the code of the C# method:

  public static float Add(float A, float B)
  {
        return A + B;
  }

Here's the result VS2015SP2 / Release + Optimizations turned on. Just to make sure: Here`s the csc command line from the build:

C:\Program Files (x86)\MSBuild\14.0\bin\csc.exe /noconfig /nowarn:1701,1702,2008 /nostdlib+ /platform:anycpu32bitpreferred /errorreport:prompt /warn:4 /define:TRACE /errorendlocation /preferreduilang:en-US /highentropyva+ /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\Microsoft.CSharp.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\mscorlib.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Core.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Data.DataSetExtensions.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Data.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Net.Http.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Xml.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5.2\System.Xml.Linq.dll" /debug- /filealign:512 /optimize+ /out:obj\Release\ConsoleApplication1.exe /ruleset:"C:\Program Files (x86)\Microsoft Visual Studio 14.0\Team Tools\Static Analysis Tools\Rule Sets\MinimumRecommendedRules.ruleset" /subsystemversion:6.00 /target:exe /utf8output Program.cs Properties\AssemblyInfo.cs "C:\Users\Martin\AppData\Local\Temp.NETFramework,Version=v4.5.2.AssemblyAttributes.cs" obj\Release\TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs obj\Release\TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs obj\Release\TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs (TaskId:27) 1>

    .method public hidebysig static 
    float32 Add (
        float32 A,
        float32 B
    ) cil managed 
{
    // Method begins at RVA 0x2054
    // Code size 9 (0x9)
    .maxstack 2
    .locals init (
        [0] float32
    )

    IL_0000: nop
    IL_0001: ldarg.0
    IL_0002: ldarg.1
    IL_0003: add
    IL_0004: stloc.0
    IL_0005: br.s IL_0007

    IL_0007: ldloc.0
    IL_0008: ret
} // end of method Program::Add

Do you know any reason why there is still nop in it, why there's a local variable and why there's a jump at the end that does nothing?

It's clear to me that the final jitter might solve this, but if I see this I don't know, if I can trust the jitter.

Thanks Martin


Solution

  • I'm afraid I cannot repeat your results. Compiling with csc /debug- /optimize+ and then using ildasm, I get:

    .method public hidebysig static float32  Add(float32 A,
                                                 float32 B) cil managed
    {
      // Code size       4 (0x4)
      .maxstack  8
      IL_0000:  ldarg.0
      IL_0001:  ldarg.1
      IL_0002:  add
      IL_0003:  ret
    } // end of method Program::Add
    

    which is what I'd expect from optimized code. Indeed if I change to optimize-, I get the code you posted. Are you checking a Debug vs. Release subdirectory perhaps?