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

Alternative fix for folding of *(typ*)&lclVar for small types #40607 #40871

Merged
merged 5 commits into from
Sep 3, 2020

Conversation

echesakov
Copy link
Contributor

@echesakov echesakov commented Aug 15, 2020

The code generated on DependsOnUnInitValue make an assumption that upper 3 bytes of [rsp+04H] location were zero-ed and reads the value as "full" int (i.e. doesn't normalize the value on load).

G_M48546_IG01:
       50                   push     rax
                                                ;; bbWeight=1    PerfScore 1.00
G_M48546_IG02:
       B801000000           mov      eax, 1
       EB04                 jmp      SHORT G_M48546_IG04
                                                ;; bbWeight=1    PerfScore 2.25
G_M48546_IG03:
       33C0                 xor      eax, eax
       EB0C                 jmp      SHORT G_M48546_IG05
                                                ;; bbWeight=0.50 PerfScore 1.12
G_M48546_IG04:
       C644240400           mov      byte  ptr [rsp+04H], 0
       837C240400           cmp      dword ptr [rsp+04H], 0
       75F0                 jne      SHORT G_M48546_IG03
                                                ;; bbWeight=1    PerfScore 3.00
G_M48546_IG05:
       4883C408             add      rsp, 8
       C3                   ret
                                                ;; bbWeight=1    PerfScore 1.25

@echesakov echesakov added area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI and removed area-ReadyToRun-coreclr labels Aug 15, 2020
@echesakov
Copy link
Contributor Author

I think the issue here could be categorized as another instance of now closed #620

It seems that the changes in #40535 didn't address the issue completely and the following describes why.

Setting varDsc->lvForceLoadNormalize on stores in fgMorphSmpOp is too late since we might have already morphed a load of local varDsc and treated such local as not lvNormalizeOnLoad.

In the PR example, the execution chain will always follow BB01 -> BB04 -> BB02 and BB02 contains not normalized load of V01 and BB04 contains IND(ADDR(LCL_VAR)) folded into LCL_FLD.

Morphing BB01 of 'Runtime_40607.Program:DependsOnUnInitValue():int'

fgMorphTree BB01, STMT00000 (before)
               [000002] -A----------              *  ASG       int   
               [000001] D------N----              +--*  LCL_VAR   int    V00 loc0         
               [000000] ------------              \--*  CNS_INT   int    1
GenTreeNode creates assertion:
               [000002] -A----------              *  ASG       int   
In BB01 New Local Constant Assertion: V00 == 1 index=#01, mask=0000000000000001

Morphing BB02 of 'Runtime_40607.Program:DependsOnUnInitValue():int'

fgMorphTree BB02, STMT00003 (before)
               [000013] ------------              *  JTRUE     void  
               [000012] ------------              \--*  EQ        int   
               [000010] ------------                 +--*  LCL_VAR   int    V01 loc1         
               [000011] ------------                 \--*  CNS_INT   int    0

Morphing BB03 of 'Runtime_40607.Program:DependsOnUnInitValue():int'

fgMorphTree BB03, STMT00004 (before)
               [000016] -A----------              *  ASG       int   
               [000015] D------N----              +--*  LCL_VAR   int    V00 loc0         
               [000014] ------------              \--*  CNS_INT   int    0
GenTreeNode creates assertion:
               [000016] -A----------              *  ASG       int   
In BB03 New Local Constant Assertion: V00 == 0 index=#01, mask=0000000000000001

Morphing BB04 of 'Runtime_40607.Program:DependsOnUnInitValue():int'

fgMorphTree BB04, STMT00006 (before)
               [000023] -A-XG-------              *  ASG       byte  
               [000022] *------N----              +--*  IND       byte  
               [000019] ------------              |  \--*  ADDR      long  
               [000020] -------N----              |     \--*  LCL_VAR   int    V01 loc1         
               [000021] ------------              \--*  CNS_INT   int    0

Local V01 should not be enregistered because: was accessed as a local field

fgMorphTree BB04, STMT00006 (after)
               [000023] -A--G+------              *  ASG       byte  
               [000020] U----+-N----              +--*  LCL_FLD   byte   V01 loc1         [+0]
               [000021] -----+------              \--*  CNS_INT   int    0

fgMorphTree BB04, STMT00002 (before)
               [000009] ------------              *  NOP       void  


Morphing BB05 of 'Runtime_40607.Program:DependsOnUnInitValue():int'

fgMorphTree BB05, STMT00005 (before)
               [000018] ------------              *  RETURN    int   
               [000017] ------------              \--*  LCL_VAR   int    V00 loc0      

As a consequence, the JIT generates cmp dword ptr [rsp+04H], 0 for the corresponding tree in BB02 that depends on the uninitialized value on the stack (since the method is marked as SkipLocalsInit).

The test in #40607 started failing after #40535 was merged that made such case more likely to fail (but I don't think it introduced the issue).

As a one of the low risk solutions, we can move check for the narrowing stores and move setting of varDsc->lvForceLoadNormalize to EscapeLocation in lclmorph.cpp. But I personally don't like this solution, since we would be making assumption in local morph about further optimizations in global morph.

Making such locals addressed exposed introduces 3 kbytes of regressions in S.P.C alone, so this option doesn't look viable.

@dotnet/jit-contrib Any other ideas? This is silent bad codegen issue, so perhaps, we want to fix this in 5.0?

@sandreenko
Copy link
Contributor

As a one of the low risk solutions, we can move check for the narrowing stores and move setting of varDsc->lvForceLoadNormalize to EscapeLocation in lclmorph.cpp. But I personally don't like this solution, since we would be making assumption in local morph about further optimizations in global morph.

Another option could be to make the transformation in lclmorph so after this phase we could have only one of 2 possible states:

  1. varDsc->lvForceLoadNormalize == true, all loads will be transformed by morph;
  2. varDsc->lvForceLoadNormalize ==false, no optimizations required.

@echesakov
Copy link
Contributor Author

@dotnet/jit-contrib The approach in 47a9b26 seems to be working on the existing set of tests and gives quite favorable diffs

Found 9 files with textual diffs.

Summary of Code Size diffs:
(Lower is better)

Total bytes of diff: -1459 (-0.00% of base)
    diff is an improvement.

Top file improvements (bytes):
       -1125 : System.Private.CoreLib.dasm (-0.03% of base)
        -129 : Microsoft.CodeAnalysis.CSharp.dasm (-0.01% of base)
         -76 : System.Text.Json.dasm (-0.02% of base)
         -52 : System.Private.Xml.dasm (-0.00% of base)
         -24 : System.CodeDom.dasm (-0.01% of base)
         -22 : Microsoft.CodeAnalysis.VisualBasic.dasm (-0.00% of base)
         -13 : Microsoft.Diagnostics.FastSerialization.dasm (-0.04% of base)
         -12 : Microsoft.CSharp.dasm (-0.00% of base)
          -6 : Microsoft.CodeAnalysis.dasm (-0.00% of base)

9 total files with Code Size differences (9 improved, 0 regressed), 256 unchanged.

Top method regressions (bytes):
          20 ( 2.28% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Rewriter:LowerBodyOrInitializer(Microsoft.CodeAnalysis.VisualBasic.Symbols.MethodSymbol,int,Microsoft.CodeAnalysis.VisualBasic.BoundBlock,Microsoft.CodeAnalysis.VisualBasic.SynthesizedSubmissionFields,Microsoft.CodeAnalysis.VisualBasic.TypeCompilationState,Microsoft.CodeAnalysis.DiagnosticBag,byref,Microsoft.CodeAnalysis.ArrayBuilder`1[LambdaDebugInfo],Microsoft.CodeAnalysis.ArrayBuilder`1[ClosureDebugInfo],byref,byref,bool,bool):Microsoft.CodeAnalysis.VisualBasic.BoundBlock
           2 ( 0.14% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.MethodToClassRewriter`1[__Canon][System.__Canon]:RewriteBlock(Microsoft.CodeAnalysis.VisualBasic.BoundBlock,Microsoft.CodeAnalysis.ArrayBuilder`1[[Microsoft.CodeAnalysis.VisualBasic.BoundExpression, Microsoft.CodeAnalysis.VisualBasic, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]],Microsoft.CodeAnalysis.ArrayBuilder`1[[Microsoft.CodeAnalysis.VisualBasic.Symbols.LocalSymbol, Microsoft.CodeAnalysis.VisualBasic, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]):Microsoft.CodeAnalysis.VisualBasic.BoundBlock:this

Top method improvements (bytes):
        -218 (-17.34% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:CompareStringIgnoreCase(byref,int,byref,int):int
        -212 (-15.49% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:IndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
        -200 (-14.87% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:LastIndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
        -182 (-28.13% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:EqualSurrogate(ushort,ushort,ushort,ushort):bool
         -91 (-11.94% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:ToUpperOrdinal(System.ReadOnlySpan`1[Char],System.Span`1[Char])
         -48 (-3.28% of base) : System.Private.CoreLib.dasm - Enumerator:MoveNext():bool:this (7 methods)
         -27 (-2.54% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Symbols.SourceMethodSymbol:EarlyDecodeWellKnownAttribute(byref):Microsoft.CodeAnalysis.VisualBasic.Symbols.VisualBasicAttributeData:this
         -24 (-2.10% of base) : System.CodeDom.dasm - Microsoft.VisualBasic.VBCodeGenerator:QuoteSnippetString(System.String):System.String:this
         -24 (-18.32% of base) : System.Private.CoreLib.dasm - System.Text.Rune:ToString():System.String:this
         -22 (-2.64% of base) : System.Private.CoreLib.dasm - System.Reflection.MdConstant:GetValue(System.Reflection.MetadataImport,int,System.RuntimeTypeHandle,bool):System.Object
         -21 (-10.77% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerLineNumberAttribute():bool:this
         -21 (-77.78% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetInt16WithAllBitsSet():short
         -20 (-76.92% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetUInt16WithAllBitsSet():ushort
         -20 (-36.36% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool
         -20 (-14.08% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetInt16WithQuotes():short:this
         -19 (-76.00% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetSByteWithAllBitsSet():byte
         -19 (-35.85% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadUInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool
         -19 (-13.48% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetSByteWithQuotes():byte:this
         -19 (-13.57% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetUInt16WithQuotes():ushort:this
         -18 (-9.47% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerFilePathAttribute():bool:this

Top method regressions (percentages):
          20 ( 2.28% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Rewriter:LowerBodyOrInitializer(Microsoft.CodeAnalysis.VisualBasic.Symbols.MethodSymbol,int,Microsoft.CodeAnalysis.VisualBasic.BoundBlock,Microsoft.CodeAnalysis.VisualBasic.SynthesizedSubmissionFields,Microsoft.CodeAnalysis.VisualBasic.TypeCompilationState,Microsoft.CodeAnalysis.DiagnosticBag,byref,Microsoft.CodeAnalysis.ArrayBuilder`1[LambdaDebugInfo],Microsoft.CodeAnalysis.ArrayBuilder`1[ClosureDebugInfo],byref,byref,bool,bool):Microsoft.CodeAnalysis.VisualBasic.BoundBlock
           2 ( 0.14% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.MethodToClassRewriter`1[__Canon][System.__Canon]:RewriteBlock(Microsoft.CodeAnalysis.VisualBasic.BoundBlock,Microsoft.CodeAnalysis.ArrayBuilder`1[[Microsoft.CodeAnalysis.VisualBasic.BoundExpression, Microsoft.CodeAnalysis.VisualBasic, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]],Microsoft.CodeAnalysis.ArrayBuilder`1[[Microsoft.CodeAnalysis.VisualBasic.Symbols.LocalSymbol, Microsoft.CodeAnalysis.VisualBasic, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]):Microsoft.CodeAnalysis.VisualBasic.BoundBlock:this

Top method improvements (percentages):
         -21 (-77.78% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetInt16WithAllBitsSet():short
         -20 (-76.92% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetUInt16WithAllBitsSet():ushort
         -19 (-76.00% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetSByteWithAllBitsSet():byte
         -18 (-75.00% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetByteWithAllBitsSet():ubyte
         -20 (-36.36% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool
         -19 (-35.85% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadUInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool
        -182 (-28.13% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:EqualSurrogate(ushort,ushort,ushort,ushort):bool
         -24 (-18.32% of base) : System.Private.CoreLib.dasm - System.Text.Rune:ToString():System.String:this
        -218 (-17.34% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:CompareStringIgnoreCase(byref,int,byref,int):int
        -212 (-15.49% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:IndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
        -200 (-14.87% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:LastIndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
         -20 (-14.08% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetInt16WithQuotes():short:this
         -19 (-13.57% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetUInt16WithQuotes():ushort:this
         -19 (-13.48% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetSByteWithQuotes():byte:this
         -18 (-13.24% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetByteWithQuotes():ubyte:this
         -91 (-11.94% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:ToUpperOrdinal(System.ReadOnlySpan`1[Char],System.Span`1[Char])
         -21 (-10.77% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerLineNumberAttribute():bool:this
         -18 (-9.47% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerFilePathAttribute():bool:this
         -18 (-9.47% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerMemberNameAttribute():bool:this
         -15 (-7.21% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_IsCallerLineNumber():bool:this

40 total methods with Code Size differences (38 improved, 2 regressed), 232194 unchanged.

However, I don't like using (tree->gtFlags & GTF_DONT_CSE) != 0 to determine whether we on the lhs or rhs of an assignment.
Any suggestions how this could be improved?

@AndyAyersMS
Copy link
Member

Wonder if we could do the bookkeeping in the MorphAddrContext?

@echesakov echesakov changed the title Add regression test for #40607 Potential fix for folding of IND(ADDR(LCLVAR( for small types #40607 Aug 29, 2020
@echesakov
Copy link
Contributor Author

Wonder if we could do the bookkeeping in the MorphAddrContext?

I guess we can, but I wonder if can simply set GTF_IND_ASG_LHS in pre-order morph instead.
Can this potential harm anything if done earlier than now?

@echesakov
Copy link
Contributor Author

echesakov commented Aug 29, 2020

I added more tests to cover possible variants of loads.

I also added small optimization to cover folding of IND(ADDR(LCL_VAR))) that are r-values and signedness of indirection and local types are mismatched (byte <-> sbyte) I believe we can do simple casting when the local does not require normalization on load instead fallback to lclFld that would forbid such local from enregistering.

@echesakov
Copy link
Contributor Author

I triggered jitstress pipelines of coreclr tests and libraries tests and enabled the originally failing test.

@echesakov echesakov changed the title Potential fix for folding of IND(ADDR(LCLVAR( for small types #40607 Potential fix for folding of *(typ*)&lclVar for small types #40607 Aug 29, 2020
@echesakov
Copy link
Contributor Author

Failure in runtime-coreclr libraries-jitstress (Libraries Test Run checked coreclr Linux arm Release) is #36752

@echesakov
Copy link
Contributor Author

The following are the jit diffs for the change

win-x64

Found 9 files with textual diffs.

Summary of Code Size diffs:
(Lower is better)

Total bytes of diff: -1474 (-0.00% of base)
    diff is an improvement.

Top file improvements (bytes):
       -1140 : System.Private.CoreLib.dasm (-0.03% of base)
        -129 : Microsoft.CodeAnalysis.CSharp.dasm (-0.01% of base)
         -76 : System.Text.Json.dasm (-0.02% of base)
         -52 : System.Private.Xml.dasm (-0.00% of base)
         -24 : System.CodeDom.dasm (-0.01% of base)
         -22 : Microsoft.CodeAnalysis.VisualBasic.dasm (-0.00% of base)
         -13 : Microsoft.Diagnostics.FastSerialization.dasm (-0.04% of base)
         -12 : Microsoft.CSharp.dasm (-0.00% of base)
          -6 : Microsoft.CodeAnalysis.dasm (-0.00% of base)

9 total files with Code Size differences (9 improved, 0 regressed), 256 unchanged.

Top method regressions (bytes):
          20 ( 2.28% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Rewriter:LowerBodyOrInitializer(Microsoft.CodeAnalysis.VisualBasic.Symbols.MethodSymbol,int,Microsoft.CodeAnalysis.VisualBasic.BoundBlock,Microsoft.CodeAnalysis.VisualBasic.SynthesizedSubmissionFields,Microsoft.CodeAnalysis.VisualBasic.TypeCompilationState,Microsoft.CodeAnalysis.DiagnosticBag,byref,Microsoft.CodeAnalysis.ArrayBuilder`1[LambdaDebugInfo],Microsoft.CodeAnalysis.ArrayBuilder`1[ClosureDebugInfo],byref,byref,bool,bool):Microsoft.CodeAnalysis.VisualBasic.BoundBlock
           2 ( 0.14% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.MethodToClassRewriter`1[__Canon][System.__Canon]:RewriteBlock(Microsoft.CodeAnalysis.VisualBasic.BoundBlock,Microsoft.CodeAnalysis.ArrayBuilder`1[[Microsoft.CodeAnalysis.VisualBasic.BoundExpression, Microsoft.CodeAnalysis.VisualBasic, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]],Microsoft.CodeAnalysis.ArrayBuilder`1[[Microsoft.CodeAnalysis.VisualBasic.Symbols.LocalSymbol, Microsoft.CodeAnalysis.VisualBasic, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]):Microsoft.CodeAnalysis.VisualBasic.BoundBlock:this

Top method improvements (bytes):
        -218 (-17.34% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:CompareStringIgnoreCase(byref,int,byref,int):int
        -212 (-15.49% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:IndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
        -200 (-14.87% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:LastIndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
        -182 (-28.13% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:EqualSurrogate(ushort,ushort,ushort,ushort):bool
         -91 (-11.94% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:ToUpperOrdinal(System.ReadOnlySpan`1[Char],System.Span`1[Char])
         -48 (-3.28% of base) : System.Private.CoreLib.dasm - Enumerator:MoveNext():bool:this (7 methods)
         -27 (-2.54% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Symbols.SourceMethodSymbol:EarlyDecodeWellKnownAttribute(byref):Microsoft.CodeAnalysis.VisualBasic.Symbols.VisualBasicAttributeData:this
         -24 (-2.10% of base) : System.CodeDom.dasm - Microsoft.VisualBasic.VBCodeGenerator:QuoteSnippetString(System.String):System.String:this
         -24 (-18.32% of base) : System.Private.CoreLib.dasm - System.Text.Rune:ToString():System.String:this
         -22 (-2.64% of base) : System.Private.CoreLib.dasm - System.Reflection.MdConstant:GetValue(System.Reflection.MetadataImport,int,System.RuntimeTypeHandle,bool):System.Object
         -21 (-10.77% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerLineNumberAttribute():bool:this
         -21 (-77.78% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetInt16WithAllBitsSet():short
         -20 (-76.92% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetUInt16WithAllBitsSet():ushort
         -20 (-36.36% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool
         -20 (-14.08% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetInt16WithQuotes():short:this
         -19 (-76.00% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetSByteWithAllBitsSet():byte
         -19 (-35.85% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadUInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool
         -19 (-13.48% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetSByteWithQuotes():byte:this
         -19 (-13.57% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetUInt16WithQuotes():ushort:this
         -18 (-9.47% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerFilePathAttribute():bool:this

Top method regressions (percentages):
          20 ( 2.28% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Rewriter:LowerBodyOrInitializer(Microsoft.CodeAnalysis.VisualBasic.Symbols.MethodSymbol,int,Microsoft.CodeAnalysis.VisualBasic.BoundBlock,Microsoft.CodeAnalysis.VisualBasic.SynthesizedSubmissionFields,Microsoft.CodeAnalysis.VisualBasic.TypeCompilationState,Microsoft.CodeAnalysis.DiagnosticBag,byref,Microsoft.CodeAnalysis.ArrayBuilder`1[LambdaDebugInfo],Microsoft.CodeAnalysis.ArrayBuilder`1[ClosureDebugInfo],byref,byref,bool,bool):Microsoft.CodeAnalysis.VisualBasic.BoundBlock
           2 ( 0.14% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.MethodToClassRewriter`1[__Canon][System.__Canon]:RewriteBlock(Microsoft.CodeAnalysis.VisualBasic.BoundBlock,Microsoft.CodeAnalysis.ArrayBuilder`1[[Microsoft.CodeAnalysis.VisualBasic.BoundExpression, Microsoft.CodeAnalysis.VisualBasic, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]],Microsoft.CodeAnalysis.ArrayBuilder`1[[Microsoft.CodeAnalysis.VisualBasic.Symbols.LocalSymbol, Microsoft.CodeAnalysis.VisualBasic, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]):Microsoft.CodeAnalysis.VisualBasic.BoundBlock:this

Top method improvements (percentages):
         -21 (-77.78% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetInt16WithAllBitsSet():short
         -20 (-76.92% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetUInt16WithAllBitsSet():ushort
         -19 (-76.00% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetSByteWithAllBitsSet():byte
         -18 (-75.00% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetByteWithAllBitsSet():ubyte
         -20 (-36.36% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool
         -19 (-35.85% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadUInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool
         -15 (-34.88% of base) : System.Private.CoreLib.dasm - System.Span`1[SByte][System.SByte]:Fill(byte):this
        -182 (-28.13% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:EqualSurrogate(ushort,ushort,ushort,ushort):bool
         -24 (-18.32% of base) : System.Private.CoreLib.dasm - System.Text.Rune:ToString():System.String:this
        -218 (-17.34% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:CompareStringIgnoreCase(byref,int,byref,int):int
        -212 (-15.49% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:IndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
        -200 (-14.87% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:LastIndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
         -20 (-14.08% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetInt16WithQuotes():short:this
         -19 (-13.57% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetUInt16WithQuotes():ushort:this
         -19 (-13.48% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetSByteWithQuotes():byte:this
         -18 (-13.24% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetByteWithQuotes():ubyte:this
         -91 (-11.94% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:ToUpperOrdinal(System.ReadOnlySpan`1[Char],System.Span`1[Char])
         -21 (-10.77% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerLineNumberAttribute():bool:this
         -18 (-9.47% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerFilePathAttribute():bool:this
         -18 (-9.47% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerMemberNameAttribute():bool:this

41 total methods with Code Size differences (39 improved, 2 regressed), 232193 unchanged.

win-x86

Found 9 files with textual diffs.

Summary of Code Size diffs:
(Lower is better)

Total bytes of diff: -1043 (-0.00% of base)
    diff is an improvement.

Top file improvements (bytes):
        -797 : System.Private.CoreLib.dasm (-0.03% of base)
         -97 : Microsoft.CodeAnalysis.CSharp.dasm (-0.01% of base)
         -58 : System.Private.Xml.dasm (-0.00% of base)
         -38 : System.Text.Json.dasm (-0.01% of base)
         -16 : Microsoft.CodeAnalysis.VisualBasic.dasm (-0.00% of base)
         -10 : Microsoft.CSharp.dasm (-0.00% of base)
         -10 : Microsoft.Diagnostics.FastSerialization.dasm (-0.03% of base)
          -9 : System.CodeDom.dasm (-0.01% of base)
          -8 : Microsoft.CodeAnalysis.dasm (-0.00% of base)

9 total files with Code Size differences (9 improved, 0 regressed), 256 unchanged.

Top method regressions (bytes):
           6 ( 0.51% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.MethodToClassRewriter`1[__Canon][System.__Canon]:RewriteBlock(Microsoft.CodeAnalysis.VisualBasic.BoundBlock,Microsoft.CodeAnalysis.ArrayBuilder`1[[Microsoft.CodeAnalysis.VisualBasic.BoundExpression, Microsoft.CodeAnalysis.VisualBasic, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]],Microsoft.CodeAnalysis.ArrayBuilder`1[[Microsoft.CodeAnalysis.VisualBasic.Symbols.LocalSymbol, Microsoft.CodeAnalysis.VisualBasic, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]):Microsoft.CodeAnalysis.VisualBasic.BoundBlock:this
           2 ( 0.31% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Rewriter:LowerBodyOrInitializer(Microsoft.CodeAnalysis.VisualBasic.Symbols.MethodSymbol,int,Microsoft.CodeAnalysis.VisualBasic.BoundBlock,Microsoft.CodeAnalysis.VisualBasic.SynthesizedSubmissionFields,Microsoft.CodeAnalysis.VisualBasic.TypeCompilationState,Microsoft.CodeAnalysis.DiagnosticBag,byref,Microsoft.CodeAnalysis.ArrayBuilder`1[LambdaDebugInfo],Microsoft.CodeAnalysis.ArrayBuilder`1[ClosureDebugInfo],byref,byref,bool,bool):Microsoft.CodeAnalysis.VisualBasic.BoundBlock
           2 ( 0.24% of base) : System.Private.CoreLib.dasm - System.Diagnostics.Tracing.EventSource:InitializeProviderMetadata():this

Top method improvements (bytes):
        -182 (-29.74% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:EqualSurrogate(ushort,ushort,ushort,ushort):bool
        -156 (-12.12% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:LastIndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
        -116 (-9.50% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:CompareStringIgnoreCase(byref,int,byref,int):int
         -96 (-7.47% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:IndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
         -72 (-10.73% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:ToUpperOrdinal(System.ReadOnlySpan`1[Char],System.Span`1[Char])
         -40 (-3.21% of base) : System.Private.CoreLib.dasm - Enumerator:MoveNext():bool:this (7 methods)
         -29 (-22.66% of base) : System.Private.CoreLib.dasm - System.Text.Rune:ToString():System.String:this
         -24 (-0.93% of base) : System.Private.Xml.dasm - System.Xml.XmlConvert:DecodeName(System.String):System.String
         -20 (-2.42% of base) : System.Private.CoreLib.dasm - System.Reflection.MdConstant:GetValue(System.Reflection.MetadataImport,int,System.RuntimeTypeHandle,bool):System.Object
         -16 (-1.36% of base) : System.Private.Xml.dasm - System.Xml.XmlTextReaderImpl:ParseNumericCharRefInline(int,bool,System.Text.StringBuilder,byref,byref):int:this
         -15 (-8.67% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_IsCallerLineNumber():bool:this
         -15 (-8.11% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_IsCallerFilePath():bool:this
         -15 (-10.56% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerFilePathAttribute():bool:this
         -15 (-7.61% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_IsCallerMemberName():bool:this
         -15 (-10.56% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerMemberNameAttribute():bool:this
         -14 (-70.00% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetUInt16WithAllBitsSet():ushort
         -14 (-70.00% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetInt16WithAllBitsSet():short
         -13 (-1.58% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Symbols.SourceMethodSymbol:EarlyDecodeWellKnownAttribute(byref):Microsoft.CodeAnalysis.VisualBasic.Symbols.VisualBasicAttributeData:this
         -13 (-20.63% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool
         -13 (-20.63% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadUInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool

Top method regressions (percentages):
           6 ( 0.51% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.MethodToClassRewriter`1[__Canon][System.__Canon]:RewriteBlock(Microsoft.CodeAnalysis.VisualBasic.BoundBlock,Microsoft.CodeAnalysis.ArrayBuilder`1[[Microsoft.CodeAnalysis.VisualBasic.BoundExpression, Microsoft.CodeAnalysis.VisualBasic, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]],Microsoft.CodeAnalysis.ArrayBuilder`1[[Microsoft.CodeAnalysis.VisualBasic.Symbols.LocalSymbol, Microsoft.CodeAnalysis.VisualBasic, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]):Microsoft.CodeAnalysis.VisualBasic.BoundBlock:this
           2 ( 0.31% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Rewriter:LowerBodyOrInitializer(Microsoft.CodeAnalysis.VisualBasic.Symbols.MethodSymbol,int,Microsoft.CodeAnalysis.VisualBasic.BoundBlock,Microsoft.CodeAnalysis.VisualBasic.SynthesizedSubmissionFields,Microsoft.CodeAnalysis.VisualBasic.TypeCompilationState,Microsoft.CodeAnalysis.DiagnosticBag,byref,Microsoft.CodeAnalysis.ArrayBuilder`1[LambdaDebugInfo],Microsoft.CodeAnalysis.ArrayBuilder`1[ClosureDebugInfo],byref,byref,bool,bool):Microsoft.CodeAnalysis.VisualBasic.BoundBlock
           2 ( 0.24% of base) : System.Private.CoreLib.dasm - System.Diagnostics.Tracing.EventSource:InitializeProviderMetadata():this

Top method improvements (percentages):
         -14 (-70.00% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetUInt16WithAllBitsSet():ushort
         -14 (-70.00% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetInt16WithAllBitsSet():short
         -12 (-66.67% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetByteWithAllBitsSet():ubyte
         -12 (-66.67% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetSByteWithAllBitsSet():byte
        -182 (-29.74% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:EqualSurrogate(ushort,ushort,ushort,ushort):bool
         -29 (-22.66% of base) : System.Private.CoreLib.dasm - System.Text.Rune:ToString():System.String:this
         -10 (-20.83% of base) : System.Private.CoreLib.dasm - System.Span`1[SByte][System.SByte]:Fill(byte):this
         -13 (-20.63% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool
         -13 (-20.63% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadUInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool
        -156 (-12.12% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:LastIndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
         -10 (-10.75% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetInt16WithQuotes():short:this
         -10 (-10.75% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetUInt16WithQuotes():ushort:this
         -72 (-10.73% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:ToUpperOrdinal(System.ReadOnlySpan`1[Char],System.Span`1[Char])
         -15 (-10.56% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerFilePathAttribute():bool:this
         -15 (-10.56% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerMemberNameAttribute():bool:this
          -9 (-10.11% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetByteWithQuotes():ubyte:this
          -9 (-9.78% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetSByteWithQuotes():byte:this
        -116 (-9.50% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:CompareStringIgnoreCase(byref,int,byref,int):int
         -15 (-8.67% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_IsCallerLineNumber():bool:this
         -15 (-8.11% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_IsCallerFilePath():bool:this

41 total methods with Code Size differences (38 improved, 3 regressed), 232145 unchanged.

win-arm (altjit)

Found 9 files with textual diffs.

Summary of Code Size diffs:
(Lower is better)

Total bytes of diff: -940 (-0.00% of base)
    diff is an improvement.

Top file regressions (bytes):
           6 : System.CodeDom.dasm (0.00% of base)

Top file improvements (bytes):
        -710 : System.Private.CoreLib.dasm (-0.02% of base)
         -74 : Microsoft.CodeAnalysis.CSharp.dasm (-0.00% of base)
         -52 : System.Private.Xml.dasm (-0.00% of base)
         -46 : Microsoft.CodeAnalysis.VisualBasic.dasm (-0.00% of base)
         -32 : System.Text.Json.dasm (-0.01% of base)
         -14 : Microsoft.CSharp.dasm (-0.00% of base)
         -12 : Microsoft.Diagnostics.FastSerialization.dasm (-0.04% of base)
          -6 : Microsoft.CodeAnalysis.dasm (-0.00% of base)

9 total files with Code Size differences (8 improved, 1 regressed), 256 unchanged.

Top method regressions (bytes):
           6 ( 0.58% of base) : System.CodeDom.dasm - Microsoft.VisualBasic.VBCodeGenerator:QuoteSnippetString(System.String):System.String:this

Top method improvements (bytes):
        -124 (-11.40% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:CompareStringIgnoreCase(byref,int,byref,int):int
        -122 (-20.54% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:EqualSurrogate(ushort,ushort,ushort,ushort):bool
        -110 (-9.12% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:IndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
        -110 (-9.14% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:LastIndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
         -68 (-10.33% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:ToUpperOrdinal(System.ReadOnlySpan`1[Char],System.Span`1[Char])
         -40 (-3.01% of base) : System.Private.CoreLib.dasm - Enumerator:MoveNext():bool:this (7 methods)
         -22 (-16.92% of base) : System.Private.CoreLib.dasm - System.Text.Rune:ToString():System.String:this
         -20 (-1.75% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Symbols.SourceMethodSymbol:EarlyDecodeWellKnownAttribute(byref):Microsoft.CodeAnalysis.VisualBasic.Symbols.VisualBasicAttributeData:this
         -20 (-2.35% of base) : System.Private.CoreLib.dasm - System.Reflection.MdConstant:GetValue(System.Reflection.MetadataImport,int,System.RuntimeTypeHandle,bool):System.Object
         -20 (-1.78% of base) : System.Private.Xml.dasm - System.Xml.XmlTextReaderImpl:ParseNumericCharRefInline(int,bool,System.Text.StringBuilder,byref,byref):int:this
         -16 (-72.73% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetByteWithAllBitsSet():ubyte
         -16 (-66.67% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetSByteWithAllBitsSet():byte
         -16 (-66.67% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetUInt16WithAllBitsSet():ushort
         -16 (-66.67% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetInt16WithAllBitsSet():short
         -14 (-1.26% of base) : Microsoft.CSharp.dasm - ImplicitConversion:BindNubConversion(Microsoft.CSharp.RuntimeBinder.Semantics.NullableType):bool:this
         -12 (-3.59% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.ExecutableCodeBinder:get_BinderMap():Microsoft.CodeAnalysis.SmallDictionary`2[[Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode, Microsoft.CodeAnalysis.CSharp, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35],[Microsoft.CodeAnalysis.CSharp.Binder, Microsoft.CodeAnalysis.CSharp, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]:this
         -12 (-1.34% of base) : Microsoft.Diagnostics.FastSerialization.dasm - FastSerialization.Deserializer:TryReadTagged(byref):bool:this (7 methods)
         -12 (-0.54% of base) : System.Private.Xml.dasm - System.Xml.XmlConvert:DecodeName(System.String):System.String
         -12 (-8.45% of base) : System.Private.Xml.dasm - System.Xml.XPath.XPathNavigator:CompileMatchPattern(System.String):System.Xml.XPath.XPathExpression
         -10 (-4.72% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerLineNumberAttribute():bool:this

Top method regressions (percentages):
           6 ( 0.58% of base) : System.CodeDom.dasm - Microsoft.VisualBasic.VBCodeGenerator:QuoteSnippetString(System.String):System.String:this

Top method improvements (percentages):
         -16 (-72.73% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetByteWithAllBitsSet():ubyte
         -16 (-66.67% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetSByteWithAllBitsSet():byte
         -16 (-66.67% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetUInt16WithAllBitsSet():ushort
         -16 (-66.67% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetInt16WithAllBitsSet():short
        -122 (-20.54% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:EqualSurrogate(ushort,ushort,ushort,ushort):bool
         -22 (-16.92% of base) : System.Private.CoreLib.dasm - System.Text.Rune:ToString():System.String:this
          -6 (-16.67% of base) : System.Private.CoreLib.dasm - System.Span`1[SByte][System.SByte]:Fill(byte):this
         -10 (-15.15% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadUInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool
         -10 (-14.29% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool
        -124 (-11.40% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:CompareStringIgnoreCase(byref,int,byref,int):int
         -68 (-10.33% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:ToUpperOrdinal(System.ReadOnlySpan`1[Char],System.Span`1[Char])
        -110 (-9.14% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:LastIndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
        -110 (-9.12% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:IndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
         -12 (-8.45% of base) : System.Private.Xml.dasm - System.Xml.XPath.XPathNavigator:CompileMatchPattern(System.String):System.Xml.XPath.XPathExpression
          -8 (-6.90% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetByteWithQuotes():ubyte:this
          -8 (-6.90% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetSByteWithQuotes():byte:this
          -8 (-6.90% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetInt16WithQuotes():short:this
          -8 (-6.90% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetUInt16WithQuotes():ushort:this
          -8 (-4.94% of base) : System.Private.Xml.dasm - System.Xml.XPath.XPathExpression:Compile(System.String,System.Xml.IXmlNamespaceResolver):System.Xml.XPath.XPathExpression
         -10 (-4.76% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_HasCallerFilePathAttribute():bool:this

41 total methods with Code Size differences (40 improved, 1 regressed), 210598 unchanged.

win-arm64 (altjit) - although I wouldn't trust these numbers due to #40354

Found 9 files with textual diffs.

Summary of Code Size diffs:
(Lower is better)

Total bytes of diff: -1408 (-0.00% of base)
    diff is an improvement.

Top file improvements (bytes):
        -824 : System.Private.CoreLib.dasm (-0.02% of base)
        -200 : Microsoft.CodeAnalysis.VisualBasic.dasm (-0.00% of base)
        -176 : Microsoft.CodeAnalysis.CSharp.dasm (-0.00% of base)
         -60 : System.CodeDom.dasm (-0.02% of base)
         -48 : Microsoft.CodeAnalysis.dasm (-0.00% of base)
         -48 : System.Text.Json.dasm (-0.01% of base)
         -20 : Microsoft.CSharp.dasm (-0.00% of base)
         -16 : Microsoft.Diagnostics.FastSerialization.dasm (-0.03% of base)
         -16 : System.Private.Xml.dasm (-0.00% of base)

9 total files with Code Size differences (9 improved, 0 regressed), 256 unchanged.

Top method improvements (bytes):
        -160 (-10.58% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:CompareStringIgnoreCase(byref,int,byref,int):int
        -144 (-19.46% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:EqualSurrogate(ushort,ushort,ushort,ushort):bool
        -128 (-7.67% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:IndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
        -128 (-7.69% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:LastIndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
         -64 (-2.15% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Symbols.SourceMethodSymbol:EarlyDecodeWellKnownAttribute(byref):Microsoft.CodeAnalysis.VisualBasic.Symbols.VisualBasicAttributeData:this (2 methods)
         -60 (-4.10% of base) : System.CodeDom.dasm - Microsoft.VisualBasic.VBCodeGenerator:QuoteSnippetString(System.String):System.String:this
         -48 (-4.55% of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.Collections.SmallConcurrentSetOfInts:Add(Microsoft.CodeAnalysis.Collections.SmallConcurrentSetOfInts,int):bool (2 methods)
         -48 (-0.67% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Binder:BindUnboundLambda(Microsoft.CodeAnalysis.VisualBasic.UnboundLambda,TargetSignature):Microsoft.CodeAnalysis.VisualBasic.BoundLambda:this (2 methods)
         -48 (-2.21% of base) : System.Private.CoreLib.dasm - Enumerator:MoveNext():bool:this (7 methods)
         -44 (-4.64% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:ToUpperOrdinal(System.ReadOnlySpan`1[Char],System.Span`1[Char])
         -32 (-3.45% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.ExecutableCodeBinder:get_BinderMap():Microsoft.CodeAnalysis.SmallDictionary`2[[Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode, Microsoft.CodeAnalysis.CSharp, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35],[Microsoft.CodeAnalysis.CSharp.Binder, Microsoft.CodeAnalysis.CSharp, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]:this (2 methods)
         -32 (-1.42% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Rewriter:LowerBodyOrInitializer(Microsoft.CodeAnalysis.VisualBasic.Symbols.MethodSymbol,int,Microsoft.CodeAnalysis.VisualBasic.BoundBlock,Microsoft.CodeAnalysis.VisualBasic.SynthesizedSubmissionFields,Microsoft.CodeAnalysis.VisualBasic.TypeCompilationState,Microsoft.CodeAnalysis.DiagnosticBag,byref,Microsoft.CodeAnalysis.ArrayBuilder`1[LambdaDebugInfo],Microsoft.CodeAnalysis.ArrayBuilder`1[ClosureDebugInfo],byref,byref,bool,bool):Microsoft.CodeAnalysis.VisualBasic.BoundBlock (2 methods)
         -32 (-0.88% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.MethodToClassRewriter`1[__Canon][System.__Canon]:RewriteBlock(Microsoft.CodeAnalysis.VisualBasic.BoundBlock,Microsoft.CodeAnalysis.ArrayBuilder`1[[Microsoft.CodeAnalysis.VisualBasic.BoundExpression, Microsoft.CodeAnalysis.VisualBasic, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]],Microsoft.CodeAnalysis.ArrayBuilder`1[[Microsoft.CodeAnalysis.VisualBasic.Symbols.LocalSymbol, Microsoft.CodeAnalysis.VisualBasic, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]):Microsoft.CodeAnalysis.VisualBasic.BoundBlock:this (2 methods)
         -28 (-2.32% of base) : System.Private.CoreLib.dasm - System.Reflection.MdConstant:GetValue(System.Reflection.MetadataImport,int,System.RuntimeTypeHandle,bool):System.Object
         -24 (-1.52% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.SourceMethodSymbol:EarlyDecodeWellKnownAttribute(byref):Microsoft.CodeAnalysis.CSharp.Symbols.CSharpAttributeData:this (2 methods)
         -24 (-3.95% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_IsCallerLineNumber():bool:this (2 methods)
         -24 (-3.61% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_IsCallerFilePath():bool:this (2 methods)
         -24 (-3.33% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE.PEParameterSymbol:get_IsCallerMemberName():bool:this (2 methods)
         -24 (-0.51% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Symbols.SourceNamedTypeSymbol:GetMyGroupCollectionAttributeData(Microsoft.CodeAnalysis.DiagnosticBag,byref,byref):Microsoft.CodeAnalysis.VisualBasic.Symbols.VisualBasicAttributeData:this (2 methods)
         -24 (-12.50% of base) : System.Private.CoreLib.dasm - System.Text.Rune:ToString():System.String:this

Top method improvements (percentages):
         -20 (-50.00% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetByteWithAllBitsSet():ubyte
         -20 (-50.00% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetSByteWithAllBitsSet():byte
         -20 (-50.00% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetUInt16WithAllBitsSet():ushort
         -20 (-50.00% of base) : System.Private.CoreLib.dasm - System.Numerics.ConstantHelper:GetInt16WithAllBitsSet():short
        -144 (-19.46% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:EqualSurrogate(ushort,ushort,ushort,ushort):bool
         -12 (-13.04% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool
         -12 (-13.04% of base) : System.Private.CoreLib.dasm - System.Buffers.Binary.BinaryPrimitives:TryReadUInt16BigEndian(System.ReadOnlySpan`1[Byte],byref):bool
         -24 (-12.50% of base) : System.Private.CoreLib.dasm - System.Text.Rune:ToString():System.String:this
        -160 (-10.58% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:CompareStringIgnoreCase(byref,int,byref,int):int
         -12 (-8.33% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetByteWithQuotes():ubyte:this
         -12 (-8.33% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetSByteWithQuotes():byte:this
         -12 (-8.33% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetInt16WithQuotes():short:this
         -12 (-8.33% of base) : System.Text.Json.dasm - System.Text.Json.Utf8JsonReader:GetUInt16WithQuotes():ushort:this
          -4 (-7.69% of base) : System.Private.CoreLib.dasm - System.Span`1[SByte][System.SByte]:Fill(byte):this
        -128 (-7.69% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:LastIndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
        -128 (-7.67% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:IndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
         -12 (-5.77% of base) : System.Private.Xml.dasm - System.Xml.XPath.XPathNavigator:CompileMatchPattern(System.String):System.Xml.XPath.XPathExpression
         -44 (-4.64% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:ToUpperOrdinal(System.ReadOnlySpan`1[Char],System.Span`1[Char])
         -48 (-4.55% of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.Collections.SmallConcurrentSetOfInts:Add(Microsoft.CodeAnalysis.Collections.SmallConcurrentSetOfInts,int):bool (2 methods)
         -60 (-4.10% of base) : System.CodeDom.dasm - Microsoft.VisualBasic.VBCodeGenerator:QuoteSnippetString(System.String):System.String:this

39 total methods with Code Size differences (39 improved, 0 regressed), 210584 unchanged.

Copy link
Contributor

@sandreenko sandreenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this change is good, it fixes some issues and I like the template test.

However, It does not look like this transformation is bug-free now, my main concern is ASG where dst is not LCL_VAR but some COMMA(smth, LCL_VAR) where VAR_FOLDED_IND is set but this condition does not catch it.

For example, we can have a tree like (after global morph):

               [000028] -A-XG+------              *  ASG       byte  
               [000051] -A-X-+-N----              +--*  COMMA     byte  
               [000048] -A---+------              |  +--*  ASG       long  
               [000047] D----+-N----              |  |  +--*  LCL_VAR   long   V05 tmp2         
               [000021] -----+------              |  |  \--*  LCL_VAR   byref  V02 loc0         
               [000052] *--X-+-N----              |  \--*  IND       byte  
               [000049] -----+------              |     \--*  LCL_VAR   long   V05 tmp2         
               [000025] -----+------              \--*  MUL       int   
               [000053] -----+------                 +--*  CAST      int <- byte <- int
               [000023] -----+------                 |  \--*  LCL_VAR   int    V00 arg0         
               [000024] -----+------                 \--*  LCL_VAR   int    V01 arg1 

or

               [000012] -A-XG+------              *  ASG       byte  
               [000027] ---XG+-N----              +--*  COMMA     byte  
               [000023] ---X-+------              |  +--*  ARR_BOUNDS_CHECK_Rng void  
               [000009] -----+------              |  |  +--*  CNS_INT   int    0
               [000022] ---X-+------              |  |  \--*  ARR_LENGTH int   
               [000008] -----+------              |  |     \--*  LCL_VAR   ref    V03 tmp1         
               [000011] a---G+-N----              |  \--*  IND       byte  
               [000026] -----+------              |     \--*  ADD       byref 
               [000020] -----+------              |        +--*  LCL_VAR   ref    V03 tmp1         
               [000025] -----+------              |        \--*  CNS_INT   long   16 Fseq[#FirstElem]
               [000010] -----+------              \--*  LCL_VAR   int    V01 arg1     

and many others, I don't think we have confidence that none of them could hide VAR_FOLDED_IND.

src/coreclr/src/jit/morph.cpp Show resolved Hide resolved
src/coreclr/src/jit/morph.cpp Outdated Show resolved Hide resolved
src/coreclr/src/jit/morph.cpp Outdated Show resolved Hide resolved
src/coreclr/src/jit/morph.cpp Outdated Show resolved Hide resolved
@echesakov
Copy link
Contributor Author

Top 4 method improvements disassembly diffs:

GetByteWithAllBitsSet

diff --git a/base/GetByteWithAllBitsSet.dasm b/diff/GetByteWithAllBitsSet.dasm
index d56a5bd..2d00fcd 100644
--- a/base/GetByteWithAllBitsSet.dasm
+++ b/diff/GetByteWithAllBitsSet.dasm
@@ -6,25 +6,19 @@
 ; partially interruptible
 ; Final local variable assignments
 ;
-;  V00 loc0         [V00,T00] (  3,  3   )   ubyte  ->  [rsp+0x04]   do-not-enreg[F] ld-addr-op
+;* V00 loc0         [V00,T00] (  0,  0   )   ubyte  ->  zero-ref    ld-addr-op
 ;# V01 OutArgs      [V01    ] (  1,  1   )  lclBlk ( 0) [rsp+0x00]   "OutgoingArgSpace"
 ;
-; Lcl frame size = 8
+; Lcl frame size = 0
 
 G_M54416_IG01:
-       push     rax
-						;; bbWeight=1    PerfScore 1.00
+						;; bbWeight=1    PerfScore 0.00
 G_M54416_IG02:
-       xor      eax, eax
-       mov      dword ptr [rsp+04H], eax
-       mov      byte  ptr [rsp+04H], 255
-       mov      eax, dword ptr [rsp+04H]
-       movzx    rax, al
-						;; bbWeight=1    PerfScore 3.50
+       mov      eax, 255
+						;; bbWeight=1    PerfScore 0.25
 G_M54416_IG03:
-       add      rsp, 8
        ret      
-						;; bbWeight=1    PerfScore 1.25
+						;; bbWeight=1    PerfScore 1.00
 
-; Total bytes of code 24, prolog size 1, PerfScore 8.15, (MethodHash=98492b6f) for method System.Numerics.ConstantHelper:GetByteWithAllBitsSet():ubyte
+; Total bytes of code 6, prolog size 0, PerfScore 1.85, (MethodHash=98492b6f) for method System.Numerics.ConstantHelper:GetByteWithAllBitsSet():ubyte

GetInt16WithAllBitsSet

diff --git a/base/GetInt16WithAllBitsSet.dasm b/diff/GetInt16WithAllBitsSet.dasm
index 62b1ebd..bca7621 100644
--- a/base/GetInt16WithAllBitsSet.dasm
+++ b/diff/GetInt16WithAllBitsSet.dasm
@@ -6,25 +6,19 @@
 ; partially interruptible
 ; Final local variable assignments
 ;
-;  V00 loc0         [V00,T00] (  3,  3   )   short  ->  [rsp+0x04]   do-not-enreg[F] ld-addr-op
+;* V00 loc0         [V00,T00] (  0,  0   )   short  ->  zero-ref    ld-addr-op
 ;# V01 OutArgs      [V01    ] (  1,  1   )  lclBlk ( 0) [rsp+0x00]   "OutgoingArgSpace"
 ;
-; Lcl frame size = 8
+; Lcl frame size = 0
 
 G_M60291_IG01:
-       push     rax
-						;; bbWeight=1    PerfScore 1.00
+						;; bbWeight=1    PerfScore 0.00
 G_M60291_IG02:
-       xor      eax, eax
-       mov      dword ptr [rsp+04H], eax
-       mov      word  ptr [rsp+04H], -1
-       mov      eax, dword ptr [rsp+04H]
-       movsx    rax, ax
-						;; bbWeight=1    PerfScore 3.50
+       mov      eax, -1
+						;; bbWeight=1    PerfScore 0.25
 G_M60291_IG03:
-       add      rsp, 8
        ret      
-						;; bbWeight=1    PerfScore 1.25
+						;; bbWeight=1    PerfScore 1.00
 
-; Total bytes of code 27, prolog size 1, PerfScore 8.45, (MethodHash=7108147c) for method System.Numerics.ConstantHelper:GetInt16WithAllBitsSet():short
+; Total bytes of code 6, prolog size 0, PerfScore 1.85, (MethodHash=7108147c) for method System.Numerics.ConstantHelper:GetInt16WithAllBitsSet():short

GetSByteWithAllBitsSet

diff --git a/base/GetSByteWithAllBitsSet.dasm b/diff/GetSByteWithAllBitsSet.dasm
index 19061db..227a3f8 100644
--- a/base/GetSByteWithAllBitsSet.dasm
+++ b/diff/GetSByteWithAllBitsSet.dasm
@@ -6,25 +6,19 @@
 ; partially interruptible
 ; Final local variable assignments
 ;
-;  V00 loc0         [V00,T00] (  3,  3   )    byte  ->  [rsp+0x04]   do-not-enreg[F] ld-addr-op
+;* V00 loc0         [V00,T00] (  0,  0   )    byte  ->  zero-ref    ld-addr-op
 ;# V01 OutArgs      [V01    ] (  1,  1   )  lclBlk ( 0) [rsp+0x00]   "OutgoingArgSpace"
 ;
-; Lcl frame size = 8
+; Lcl frame size = 0
 
 G_M17686_IG01:
-       push     rax
-						;; bbWeight=1    PerfScore 1.00
+						;; bbWeight=1    PerfScore 0.00
 G_M17686_IG02:
-       xor      eax, eax
-       mov      dword ptr [rsp+04H], eax
-       mov      byte  ptr [rsp+04H], -1
-       mov      eax, dword ptr [rsp+04H]
-       movsx    rax, al
-						;; bbWeight=1    PerfScore 3.50
+       mov      eax, -1
+						;; bbWeight=1    PerfScore 0.25
 G_M17686_IG03:
-       add      rsp, 8
        ret      
-						;; bbWeight=1    PerfScore 1.25
+						;; bbWeight=1    PerfScore 1.00
 
-; Total bytes of code 25, prolog size 1, PerfScore 8.25, (MethodHash=a68abae9) for method System.Numerics.ConstantHelper:GetSByteWithAllBitsSet():byte
+; Total bytes of code 6, prolog size 0, PerfScore 1.85, (MethodHash=a68abae9) for method System.Numerics.ConstantHelper:GetSByteWithAllBitsSet():byte

GetUInt16WithAllBitsSet

diff --git a/base/GetUInt16WithAllBitsSet.dasm b/diff/GetUInt16WithAllBitsSet.dasm
index cbecdb0..d59d84e 100644
--- a/base/GetUInt16WithAllBitsSet.dasm
+++ b/diff/GetUInt16WithAllBitsSet.dasm
@@ -6,25 +6,19 @@
 ; partially interruptible
 ; Final local variable assignments
 ;
-;  V00 loc0         [V00,T00] (  3,  3   )  ushort  ->  [rsp+0x04]   do-not-enreg[F] ld-addr-op
+;* V00 loc0         [V00,T00] (  0,  0   )  ushort  ->  zero-ref    ld-addr-op
 ;# V01 OutArgs      [V01    ] (  1,  1   )  lclBlk ( 0) [rsp+0x00]   "OutgoingArgSpace"
 ;
-; Lcl frame size = 8
+; Lcl frame size = 0
 
 G_M13827_IG01:
-       push     rax
-						;; bbWeight=1    PerfScore 1.00
+						;; bbWeight=1    PerfScore 0.00
 G_M13827_IG02:
-       xor      eax, eax
-       mov      dword ptr [rsp+04H], eax
-       mov      word  ptr [rsp+04H], 0xFFFF
-       mov      eax, dword ptr [rsp+04H]
-       movzx    rax, ax
-						;; bbWeight=1    PerfScore 3.50
+       mov      eax, 0xFFFF
+						;; bbWeight=1    PerfScore 0.25
 G_M13827_IG03:
-       add      rsp, 8
        ret      
-						;; bbWeight=1    PerfScore 1.25
+						;; bbWeight=1    PerfScore 1.00
 
-; Total bytes of code 26, prolog size 1, PerfScore 8.35, (MethodHash=ae96c9fc) for method System.Numerics.ConstantHelper:GetUInt16WithAllBitsSet():ushort
+; Total bytes of code 6, prolog size 0, PerfScore 1.85, (MethodHash=ae96c9fc) for method System.Numerics.ConstantHelper:GetUInt16WithAllBitsSet():ushort

Copy link
Contributor

@sandreenko sandreenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for the master branch, I like definitelyLoad/possiblyStore vars and the additional testing.

Does it make sense to collect the diffs with this change with the version before #40535?

@echesakov
Copy link
Contributor Author

Does it make sense to collect the diffs with this change with the version before #40535?

I think it does - I will work on this while waiting for the tests to finish.

@echesakov
Copy link
Contributor Author

echesakov commented Sep 3, 2020

I did comparison of (reverted #40535 on top of 3522c32) - base against (these changes on top of the same commit) - diff.

win-x64

Found 1 files with textual diffs.

Summary of Code Size diffs:
(Lower is better)

Total bytes of diff: 49 (0.000% of base)
    diff is a regression.

Top file regressions (bytes):
          49 : System.Private.CoreLib.dasm (0.001% of base)

1 total files with Code Size differences (0 improved, 1 regressed), 264 unchanged.

Top method regressions (bytes):
          18 (72.000% of base) : System.Private.CoreLib.dasm - System.Span`1[SByte][System.SByte]:Fill(byte):this
           9 (0.784% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:IndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
           9 (0.792% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:LastIndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
           8 (0.776% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:CompareStringIgnoreCase(byref,int,byref,int):int
           5 (0.751% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:ToUpperOrdinal(System.ReadOnlySpan`1[Char],System.Span`1[Char])

Top method regressions (percentages):
          18 (72.000% of base) : System.Private.CoreLib.dasm - System.Span`1[SByte][System.SByte]:Fill(byte):this
           9 (0.792% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:LastIndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
           9 (0.784% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:IndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
           8 (0.776% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:CompareStringIgnoreCase(byref,int,byref,int):int
           5 (0.751% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:ToUpperOrdinal(System.ReadOnlySpan`1[Char],System.Span`1[Char])

5 total methods with Code Size differences (0 improved, 5 regressed), 232229 unchanged.

win-x86

Found 1 files with textual diffs.

Summary of Code Size diffs:
(Lower is better)

Total bytes of diff: 51 (0.000% of base)
    diff is a regression.

Top file regressions (bytes):
          51 : System.Private.CoreLib.dasm (0.002% of base)

1 total files with Code Size differences (0 improved, 1 regressed), 264 unchanged.

Top method regressions (bytes):
          13 (37.143% of base) : System.Private.CoreLib.dasm - System.Span`1[SByte][System.SByte]:Fill(byte):this
          12 (1.098% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:CompareStringIgnoreCase(byref,int,byref,int):int
          12 (1.020% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:IndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
          10 (0.892% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:LastIndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
           4 (0.672% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:ToUpperOrdinal(System.ReadOnlySpan`1[Char],System.Span`1[Char])

Top method regressions (percentages):
          13 (37.143% of base) : System.Private.CoreLib.dasm - System.Span`1[SByte][System.SByte]:Fill(byte):this
          12 (1.098% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:CompareStringIgnoreCase(byref,int,byref,int):int
          12 (1.020% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:IndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
          10 (0.892% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:LastIndexOf(System.ReadOnlySpan`1[Char],System.ReadOnlySpan`1[Char]):int
           4 (0.672% of base) : System.Private.CoreLib.dasm - System.Globalization.OrdinalCasing:ToUpperOrdinal(System.ReadOnlySpan`1[Char],System.Span`1[Char])

5 total methods with Code Size differences (0 improved, 5 regressed), 232181 unchanged.

As an example, System.Span`1[SByte][System.SByte]:Fill(byte):this

public void Fill(T value)
{
if (Unsafe.SizeOf<T>() == 1)
{
uint length = (uint)_length;
if (length == 0)
return;
T tmp = value; // Avoid taking address of the "value" argument. It would regress performance of the loop below.
Unsafe.InitBlockUnaligned(ref Unsafe.As<T, byte>(ref _pointer.Value), Unsafe.As<T, byte>(ref tmp), length);
}

has the following disassembly diffs

 G_M58981_IG01:
-						;; bbWeight=1    PerfScore 0.00
+       push     rax
+						;; bbWeight=1    PerfScore 1.00
 G_M58981_IG02:
        mov      r8d, dword ptr [rcx+8]
        test     r8d, r8d
        jne      SHORT G_M58981_IG04
 						;; bbWeight=1    PerfScore 3.25
 G_M58981_IG03:
+       add      rsp, 8
        ret      
-						;; bbWeight=0.50 PerfScore 0.50
+						;; bbWeight=0.50 PerfScore 0.63
 G_M58981_IG04:
        movsx    rdx, dl
+       mov      dword ptr [rsp+04H], edx
        mov      rcx, bword ptr [rcx]
+       movzx    rdx, byte  ptr [rsp+04H]
        call     [CORINFO_HELP_MEMSET]
        nop      
-						;; bbWeight=0.50 PerfScore 2.75
+						;; bbWeight=0.50 PerfScore 3.75
 G_M58981_IG05:
+       add      rsp, 8
        ret      
-						;; bbWeight=0.50 PerfScore 0.50
+						;; bbWeight=0.50 PerfScore 0.63
 
-; Total bytes of code 25, prolog size 0, PerfScore 9.50, (MethodHash=97d3199a) for method System.Span`1[SByte][System.SByte]:Fill(byte):this
+; Total bytes of code 43, prolog size 1, PerfScore 13.55, (MethodHash=97d3199a) for method System.Span`1[SByte][System.SByte]:Fill(byte):this

The difference comes from the following subtle change in decision made by morph

base

fgMorphTree BB04, STMT00053 (before)
               [000265] -ACXG-------              *  ASG       ubyte 
               [000264] D------N----              +--*  LCL_VAR   ubyte  V11 tmp3         
               [000246] *-CXG-------              \--*  IND       ubyte 
               [000257] ------------                 \--*  ADDR      byref 
               [000258] -------N----                    \--*  LCL_VAR   int    V03 loc1         

fgMorphTree BB04, STMT00053 (after)
               [000265] -A--G+------              *  ASG       ubyte 
               [000264] D----+-N----              +--*  LCL_VAR   int    V11 tmp3         
               [000258] -----+------              \--*  LCL_VAR   int    V03 loc1         

diff

fgMorphTree BB04, STMT00053 (before)
               [000265] -ACXG-------              *  ASG       ubyte 
               [000264] D------N----              +--*  LCL_VAR   ubyte  V11 tmp3         
               [000246] *-CXG-------              \--*  IND       ubyte 
               [000257] ------------                 \--*  ADDR      byref 
               [000258] -------N----                    \--*  LCL_VAR   int    V03 loc1         

Local V03 should not be enregistered because: was accessed as a local field
GenTreeNode creates assertion:
               [000265] -A--G-------              *  ASG       ubyte 
In BB04 New Local Subrange Assertion: V11 in [0..255] index=#03, mask=0000000000000004

fgMorphTree BB04, STMT00053 (after)
               [000265] -A--G+------              *  ASG       ubyte 
               [000264] D----+-N----              +--*  LCL_VAR   int    V11 tmp3         
               [000258] -----+------              \--*  LCL_FLD   ubyte  V03 loc1         [+0]

where loc1 has type byte:

; Initial local variable assignments
;
;  V00 this            byref  this
;  V01 arg1             byte 
;  V02 loc0              int 
;  V03 loc1             byte 
;  V04 loc2             long 
;  V05 loc3            byref 
;  V06 loc4             long 
;  V07 loc5             long 
;  V08 OutArgs        lclBlk <na>  "OutgoingArgSpace"

1) it is *definitely load* and types of both indirection and local variable have the same signedness (e.g. bool and byte)
2) otherwise, fold the tree and mark the local node with GTF_VAR_FOLDED_IND
   and call fgDoNormalizeOnStore() on such nodes' parents in post-order morph.
@echesakov
Copy link
Contributor Author

echesakov commented Sep 3, 2020

Rebased on top of 5183c6e to get a clean run of jitstress pipelines and incorporate a fix for #36752.

@echesakov
Copy link
Contributor Author

@briansull PTAL

@briansull
Copy link
Contributor

I don't like using (tree->gtFlags & GTF_DONT_CSE) != 0

I didn't like that either, and an alternative is to use GTF_IND_ASG_LHS (as it means the same thing as is used for building SSA)
This has to work on a few other nodes as well.
I have a working changeset with this change.
I can check it in after your change goes in.

Copy link
Contributor

@briansull briansull left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks Great
Thanks for this work.

@echesakov echesakov merged commit 31e3508 into dotnet:master Sep 3, 2020
@echesakov
Copy link
Contributor Author

/backport to release/5.0-rc2

@github-actions
Copy link
Contributor

github-actions bot commented Sep 3, 2020

Started backporting to release/5.0-rc2: https://github.com/dotnet/runtime/actions/runs/238515964

@github-actions
Copy link
Contributor

github-actions bot commented Sep 3, 2020

@echesakovMSFT backporting to release/5.0-rc2 failed, the patch most likely resulted in conflicts:

$ git am --3way --ignore-whitespace --keep-non-patch changes.patch

Applying: Add regression test for https://github.com/dotnet/runtime/issues/40607
Applying: Add Runtime_40607.tt
Applying: Add more extensive tests for loads in Runtime_40607.tt Runtime_40607.il
Applying: Enable back failing test in System.Private.Xml.dll
error: sha1 information is lacking or useless (src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/CXslTransformMultith.cs).
error: could not build fake ancestor
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Patch failed at 0004 Enable back failing test in System.Private.Xml.dll
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
Error: The process '/usr/bin/git' failed with exit code 128

Please backport manually!

@briansull briansull changed the title Potential fix for folding of *(typ*)&lclVar for small types #40607 Alternative fix for folding of *(typ*)&lclVar for small types #40607 Sep 4, 2020
@echesakov echesakov deleted the Runtime_40607 branch September 5, 2020 03:47
@ghost ghost locked as resolved and limited conversation to collaborators Dec 7, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
5 participants