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

Fold casts of constants in the importer #47133

Merged

Conversation

SingleAccretion
Copy link
Contributor

@SingleAccretion SingleAccretion commented Jan 18, 2021

See #47123 for more context. I have rerun the crossgen diffs and got some more changes, but nothing major (the regressions are still due to more inlining).

Crossgen diffs
Crossgen CodeSize Diffs for System.Private.CoreLib.dll, framework assemblies for  default jit

Summary of Code Size diffs:
(Lower is better)

Total bytes of base: 33727626
Total bytes of diff: 33727893
Total bytes of delta: 267 (0.00% of base)
    diff is a regression.

Top file regressions (bytes):
         205 : System.DirectoryServices.dasm (0.06% of base)
         121 : FSharp.Core.dasm (0.01% of base)
          86 : System.ServiceModel.Syndication.dasm (0.10% of base)
          16 : System.Private.DataContractSerialization.dasm (0.00% of base)
          11 : System.Data.Odbc.dasm (0.01% of base)
           8 : System.Security.Cryptography.Algorithms.dasm (0.00% of base)
           8 : System.Security.Cryptography.Cng.dasm (0.00% of base)
           1 : System.Memory.dasm (0.00% of base)

Top file improvements (bytes):
         -69 : System.Private.CoreLib.dasm (-0.00% of base)
         -49 : System.Net.Primitives.dasm (-0.08% of base)
         -49 : System.Private.Uri.dasm (-0.06% of base)
         -22 : Microsoft.CodeAnalysis.CSharp.dasm (-0.00% of base)

12 total files with Code Size differences (4 improved, 8 regressed), 258 unchanged.

Top method regressions (bytes):
          65 ( 7.80% of base) : FSharp.Core.dasm - HashCompare:GenericEqualityArbArray(bool,System.Collections.IEqualityComparer,System.Array,System.Array):bool
          53 (15.59% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.ActiveDirectorySite:GetComputerSite():System.DirectoryServices.ActiveDirectory.ActiveDirectorySite
          51 (10.83% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.Domain:CreateLocalSideOfTrustRelationship(System.String,int,System.String):this
          51 (10.71% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.Forest:CreateLocalSideOfTrustRelationship(System.String,int,System.String):this
          50 (33.11% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.DirectoryContext:isCurrentForest():bool:this
          46 ( 4.92% of base) : FSharp.Core.dasm - HashCompare:GenericComparisonArbArrayWithComparer(GenericComparer,System.Array,System.Array):int
          26 (36.62% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateAlternateLink(System.Uri,System.String):System.ServiceModel.Syndication.SyndicationLink
          26 (36.62% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateSelfLink(System.Uri,System.String):System.ServiceModel.Syndication.SyndicationLink
          17 ( 8.54% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:AddPermalink(System.Uri):this
          17 (25.76% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateAlternateLink(System.Uri):System.ServiceModel.Syndication.SyndicationLink
          17 (25.76% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateSelfLink(System.Uri):System.ServiceModel.Syndication.SyndicationLink
          10 ( 6.94% of base) : System.Private.DataContractSerialization.dasm - System.Xml.ValueHandle:ToULong():long:this
          10 ( 1.66% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationFeed:TryReadTextInputFromExtension(System.ServiceModel.Syndication.SyndicationElementExtensionCollection):System.ServiceModel.Syndication.SyndicationTextInput:this
           9 ( 0.67% of base) : System.Data.Odbc.dasm - System.Data.Odbc.OdbcDataReader:GetBytesOrChars(int,long,System.Array,bool,int,int):long:this
           8 ( 4.40% of base) : System.Private.CoreLib.dasm - System.Enum:ToUInt64():long:this
           8 (25.00% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:.ctor(System.Uri):this
           6 ( 1.94% of base) : System.Private.DataContractSerialization.dasm - System.Xml.ValueHandle:ToLong():long:this
           5 ( 3.16% of base) : FSharp.Core.dasm - OperatorIntrinsics:loop@5442-7(long,int):long
           5 ( 3.31% of base) : FSharp.Core.dasm - OperatorIntrinsics:loop@5442-8(long,int):long
           4 ( 0.58% of base) : System.Security.Cryptography.Algorithms.dasm - DSACng:VerifySignatureCore(System.ReadOnlySpan`1[Byte],System.ReadOnlySpan`1[Byte],int):bool:this

Top method improvements (bytes):
         -49 (-6.69% of base) : System.Net.Primitives.dasm - System.IPv4AddressHelper:ParseNonCanonical(long,int,byref,bool):long
         -49 (-6.69% of base) : System.Private.Uri.dasm - System.IPv4AddressHelper:ParseNonCanonical(long,int,byref,bool):long
         -31 (-10.73% of base) : System.Private.CoreLib.dasm - System.DateTimeOffset:.cctor()
         -23 (-16.31% of base) : System.Private.CoreLib.dasm - System.Convert:ToDateTime(System.String):System.DateTime
         -23 (-15.33% of base) : System.Private.CoreLib.dasm - System.Convert:ToDateTime(System.String,System.IFormatProvider):System.DateTime
         -22 (-4.10% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.DiagnosticsPass:FindSurprisingSignExtensionBits(Microsoft.CodeAnalysis.CSharp.BoundExpression):long
         -11 (-21.15% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationFeed:CreateLink():System.ServiceModel.Syndication.SyndicationLink:this
         -11 (-21.15% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:CreateLink():System.ServiceModel.Syndication.SyndicationLink:this
          -7 (-20.59% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:.ctor():this
          -3 (-0.47% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.Rss20FeedFormatter:ReadAlternateLink(System.Xml.XmlReader,System.Uri,System.ServiceModel.Syndication.TryParseUriCallback,bool):System.ServiceModel.Syndication.SyndicationLink
          -3 (-0.32% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.Rss20FeedFormatter:ReadMediaEnclosure(System.Xml.XmlReader,System.Uri):System.ServiceModel.Syndication.SyndicationLink:this

Top method regressions (percentages):
          26 (36.62% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateAlternateLink(System.Uri,System.String):System.ServiceModel.Syndication.SyndicationLink
          26 (36.62% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateSelfLink(System.Uri,System.String):System.ServiceModel.Syndication.SyndicationLink
          50 (33.11% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.DirectoryContext:isCurrentForest():bool:this
          17 (25.76% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateAlternateLink(System.Uri):System.ServiceModel.Syndication.SyndicationLink
          17 (25.76% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateSelfLink(System.Uri):System.ServiceModel.Syndication.SyndicationLink
           8 (25.00% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:.ctor(System.Uri):this
          53 (15.59% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.ActiveDirectorySite:GetComputerSite():System.DirectoryServices.ActiveDirectory.ActiveDirectorySite
          51 (10.83% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.Domain:CreateLocalSideOfTrustRelationship(System.String,int,System.String):this
          51 (10.71% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.Forest:CreateLocalSideOfTrustRelationship(System.String,int,System.String):this
          17 ( 8.54% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:AddPermalink(System.Uri):this
          65 ( 7.80% of base) : FSharp.Core.dasm - HashCompare:GenericEqualityArbArray(bool,System.Collections.IEqualityComparer,System.Array,System.Array):bool
          10 ( 6.94% of base) : System.Private.DataContractSerialization.dasm - System.Xml.ValueHandle:ToULong():long:this
          46 ( 4.92% of base) : FSharp.Core.dasm - HashCompare:GenericComparisonArbArrayWithComparer(GenericComparer,System.Array,System.Array):int
           8 ( 4.40% of base) : System.Private.CoreLib.dasm - System.Enum:ToUInt64():long:this
           5 ( 3.31% of base) : FSharp.Core.dasm - OperatorIntrinsics:loop@5442-8(long,int):long
           5 ( 3.16% of base) : FSharp.Core.dasm - OperatorIntrinsics:loop@5442-7(long,int):long
           6 ( 1.94% of base) : System.Private.DataContractSerialization.dasm - System.Xml.ValueHandle:ToLong():long:this
          10 ( 1.66% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationFeed:TryReadTextInputFromExtension(System.ServiceModel.Syndication.SyndicationElementExtensionCollection):System.ServiceModel.Syndication.SyndicationTextInput:this
           4 ( 1.02% of base) : System.Security.Cryptography.Cng.dasm - System.Security.Cryptography.ECDsaCng:VerifyHash(System.ReadOnlySpan`1[Byte],System.ReadOnlySpan`1[Byte]):bool:this
           4 ( 0.96% of base) : System.Security.Cryptography.Algorithms.dasm - ECDsaCng:VerifyHashCore(System.ReadOnlySpan`1[Byte],System.ReadOnlySpan`1[Byte],int):bool:this

Top method improvements (percentages):
         -11 (-21.15% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationFeed:CreateLink():System.ServiceModel.Syndication.SyndicationLink:this
         -11 (-21.15% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:CreateLink():System.ServiceModel.Syndication.SyndicationLink:this
          -7 (-20.59% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:.ctor():this
         -23 (-16.31% of base) : System.Private.CoreLib.dasm - System.Convert:ToDateTime(System.String):System.DateTime
         -23 (-15.33% of base) : System.Private.CoreLib.dasm - System.Convert:ToDateTime(System.String,System.IFormatProvider):System.DateTime
         -31 (-10.73% of base) : System.Private.CoreLib.dasm - System.DateTimeOffset:.cctor()
         -49 (-6.69% of base) : System.Net.Primitives.dasm - System.IPv4AddressHelper:ParseNonCanonical(long,int,byref,bool):long
         -49 (-6.69% of base) : System.Private.Uri.dasm - System.IPv4AddressHelper:ParseNonCanonical(long,int,byref,bool):long
         -22 (-4.10% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.DiagnosticsPass:FindSurprisingSignExtensionBits(Microsoft.CodeAnalysis.CSharp.BoundExpression):long
          -3 (-0.47% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.Rss20FeedFormatter:ReadAlternateLink(System.Xml.XmlReader,System.Uri,System.ServiceModel.Syndication.TryParseUriCallback,bool):System.ServiceModel.Syndication.SyndicationLink
          -3 (-0.32% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.Rss20FeedFormatter:ReadMediaEnclosure(System.Xml.XmlReader,System.Uri):System.ServiceModel.Syndication.SyndicationLink:this

36 total methods with Code Size differences (11 improved, 25 regressed), 236098 unchanged.
Found 48 files with textual diffs.

Example of a regression: https://www.diffchecker.com/jtOQlJX4.
Example of an improvement: https://www.diffchecker.com/7G19dkSM.

I haven't rerun the PMI diffs yet as they take a really long time on my machine (1.5 hours for two full runs) and kind of make everything else hard to use (80+ processes), and I want to ensure I have the right logic in the right place first (which is unlikely to be true as of this PR's submission). It is expected that they will be more sizeable.

Edit: looks like some things are being folded that shouldn't be. Investigating...
Edit: looks like there was a bug in the morphing of long modulus.
Edit: investigating unexpected regressions...
Edit: regressions have been analyzed, see below.

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Jan 18, 2021
@kunalspathak
Copy link
Member

I believe the test failures is due to an existing issue and it could be that your changes have exposed it.

Assert failure(PID 2196 [0x00000894], Thread: 5644 [0x160c]): Assertion failed 'OperIsSimple()' in 'DynamicClass:CallSite.Target(System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,System.Object,System.Object):System.Object' during 'Morph - Global' (IL size 142)

@SingleAccretion
Copy link
Contributor Author

I believe the test failures is due to an existing issue and it could be that your changes have exposed it.

That's possible. I have just managed to obtain the dump of the problematic method (not without some difficulties) and will report back the findings.

@kunalspathak
Copy link
Member

I believe the test failures is due to an existing issue and it could be that your changes have exposed it.

That's possible. I have just managed to obtain the dump of the problematic method (not without some difficulties) and will report back the findings.

I have a c# standalone repro for this. Let me know if you are interested or if it helps you in ease debugging.

@SingleAccretion
Copy link
Contributor Author

Let me know if you are interested

Yes, that would be great!

@kunalspathak
Copy link
Member

Let me know if you are interested

Yes, that would be great!

using System;
public class TestClass8
{
    public struct S1
    {
        public struct S1_D1_F1
        {
            public sbyte sbyte_1;
            public bool boolean_2;
            public uint uint32_3;
            public string string_4;
        }
        public S1.S1_D1_F1 s1_s1_d1_f1_2;
        public S1.S1_D1_F1 s1_s1_d1_f1_3;
        public uint uint32_4;
    }
    public struct S2
    {
        public sbyte sbyte_1;
        public S1 s1_2;
    }
    public struct S3
    {
        public S2 s2_1;
        public long int64_2;
        public struct S3_D1_F3
        {
            public ulong uint64_1;
        }
    }
    public struct S4
    {
        public decimal decimal_1;
        public S1.S1_D1_F1 s1_s1_d1_f1_2;
        public S3 s3_3;
    }
    public struct S5
    {
        public S3.S3_D1_F3 s3_s3_d1_f3_1;
    }
    public long LeafMethod7()
    {
        unchecked
        {
            int int32_6 = -1032611019 ;
            long int64_7 = 6728172856866929694L ;
            S3 s3_18 = new S3() ;
            S4 s4_19 = new S4() ;
            int loopInvariant = 1;
            return 1+2; 
        }
    }
    public ulong LeafMethod13()
    {
        unchecked
        {
            int int32_6 = 845503196 ;
            ulong uint64_13 = 12351733974017606946UL ;
            S3.S3_D1_F3 s3_s3_d1_f3_17 = new S3.S3_D1_F3() ;
            S5 s5_20 = new S5() ;
            int loopInvariant = 8;
            return uint64_13  &= 16116317412362549271UL^ uint64_13  <<= 1923055751% 4733734356262465223UL/ 17819534679104801725UL+ 93+ 89| s3_s3_d1_f3_17.uint64_1  <<= int32_6 ^ uint64_13  |= s3_s3_d1_f3_17.uint64_1  += s5_20.s3_s3_d1_f3_1.uint64_1  * s3_s3_d1_f3_17.uint64_1 / 11139180945003832152UL& s3_s3_d1_f3_17.uint64_1  %= uint64_13  /= 8589548964049453567UL+ 90+ 1| s5_20.s3_s3_d1_f3_1.uint64_1  += uint64_13  %= 17562726876373889522UL+ 17938177136826372368UL+ 83+ 68+ uint64_13  = uint64_13  <<= int32_6  &= -1209709259| uint64_13 | uint64_13  &= uint64_13 * 17623384555723108609UL% uint64_13  >>= -421932286+ 19% s3_s3_d1_f3_17.uint64_1 + 36+ s5_20.s3_s3_d1_f3_1.uint64_1  /= s5_20.s3_s3_d1_f3_1.uint64_1  <<= int32_6  &= int32_6 + s3_s3_d1_f3_17.uint64_1  <<= -970431513+ int32_6  ^= 1429190696- 12207894589152215756UL* 4967280248782330651UL+ 62; 
        }
    }
    public static void Main(string[] args)
    {
        TestClass8 objTestClass8 = new TestClass8();
        objTestClass8.Method0();
    }
    public void Method0()
    {
        unchecked
        {
            ulong uint64_13 = 12709877184972354889UL ;
            S3.S3_D1_F3 s3_s3_d1_f3_17 = new S3.S3_D1_F3() ;
            S3 s3_18 = new S3() ;
            S4 s4_19 = new S4() ;
            S5 s5_20 = new S5() ;
            int loopInvariant = 2;
            if (s4_19.s3_3.int64_2  == LeafMethod7() & s3_18.int64_2  % LeafMethod7()+ 91)
            {
                uint64_13  += LeafMethod13() / uint64_13 + 10- uint64_13  | 610171717676389549UL& 4697039689400138510UL/ s3_s3_d1_f3_17.uint64_1  %= s5_20.s3_s3_d1_f3_1.uint64_1 + 97+ 16- LeafMethod13()& LeafMethod13(); 
            }
            else
            {
                {
                    int __loopvar1 = loopInvariant - 10;
                } 
                {
                    int __loopvar1 = loopInvariant, __loopSecondaryVar1_0 = loopInvariant - 9;
                } 
            } 
            return; 
        }
    }
}
/*
Got output diff:
--------- Baseline ---------  

Environment:

COMPlus_JITMinOpts=1
COMPlus_TieredCompilation=0


--------- Test ---------  

Environment:

COMPlus_JitStress=2
COMPlus_JitStressRegs=0x80
COMPlus_TieredCompilation=0


Assert failure(PID 16648 [0x00004108], Thread: 24468 [0x5f94]): Assertion failed 'OperIsSimple()' in 'TestClass8:LeafMethod13():long:this' during 'Morph - Global' (IL size 356)

    File: D:\git\dotnet-runtime\src\coreclr\jit\gtstructs.h Line: 52
    Image: D:\git\dotnet-runtime\artifacts\tests\coreclr\windows.x64.Checked\tests\Core_Root\CoreRun.exe


*/

@SingleAccretion
Copy link
Contributor Author

After some elimination of dead ends and transcribing of IL, I was able to get to this very minimal repro:

public static ulong Problem()
{
    long a = 42;
    return (ulong)a % 42UL;
}

Will investigate what causes the assert tomorrow. The dump for the original problematic method doesn't reveal much:

Folding long operator with constant nodes into a constant:
               [000079] ------------              *  UMOD      long  
               [000076] -----+------              +--*  CNS_INT   long   3
               [000078] ------------              \--*  CNS_INT   long   3
Bashed to long constant:
               [000079] ------------              *  CNS_INT   long   0

Assert failure(PID 13452 [0x0000348c], Thread: 15176 [0x3b48]): Assertion failed 'OperIsSimple()' in 'DynamicClass:CallSite.Target(System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,System.Object,System.Object):System.Object' during 'Morph - Global' (IL size 142)

    File: C:\Users\Accretion\source\dotnet\runtime\src\coreclr\jit\gtstructs.h Line: 52
    Image: C:\Users\Accretion\source\dotnet\runtime\artifacts\bin\testhost\net6.0-windows-Debug-x64\dotnet.exe

@SingleAccretion
Copy link
Contributor Author

After (not without some difficulty) setting up the native debugger, I was able to trace the assert's origins to these lines:

runtime/src/coreclr/jit/morph.cpp

Lines 12198 to 12216 in c4421ac

if (op2->gtOper == GT_CNS_NATIVELONG && op2->AsIntConCommon()->LngValue() >= 2 &&
op2->AsIntConCommon()->LngValue() <= 0x3fffffff)
{
tree->AsOp()->gtOp1 = op1 = fgMorphTree(op1);
noway_assert(op1->TypeGet() == TYP_LONG);
// Update flags for op1 morph
tree->gtFlags &= ~GTF_ALL_EFFECT;
tree->gtFlags |= (op1->gtFlags & GTF_ALL_EFFECT); // Only update with op1 as op2 is a constant
// If op1 is a constant, then do constant folding of the division operator
if (op1->gtOper == GT_CNS_NATIVELONG)
{
tree = gtFoldExpr(tree);
}
tree->AsOp()->CheckDivideByConstOptimized(this);
return tree;

Specifically, it is the last line that asserts: tree->AsOp()->CheckDivideByConstOptimized(this);. This seems like a bug: if two previous ifs are successful, we will fold the node into a constant one, and it cannot be turned back into an operation (neither does it make sense to mark it). My proposed fix is to place it into the else branch. I will push and see if more things fail. Long division is quite rare...

Locally, it fixed both the simplified reproduction and the original test failures.

@SingleAccretion
Copy link
Contributor Author

Seeing as the CI is green, posting the final diffs:

PMI
PMI CodeSize Diffs for System.Private.CoreLib.dll, framework assemblies for  default jit

Summary of Code Size diffs:
(Lower is better)

Total bytes of base: 52088228
Total bytes of diff: 52088052
Total bytes of delta: -176 (-0.00% of base)
    diff is an improvement.

Top file regressions (bytes):
         195 : System.DirectoryServices.dasm (0.04% of base)
         183 : FSharp.Core.dasm (0.01% of base)
         152 : System.ServiceModel.Syndication.dasm (0.10% of base)
          69 : System.Net.Http.dasm (0.01% of base)
          23 : System.Private.DataContractSerialization.dasm (0.00% of base)
          14 : System.Data.Odbc.dasm (0.01% of base)

Top file improvements (bytes):
        -512 : System.Formats.Asn1.dasm (-0.46% of base)
        -164 : System.Memory.dasm (-0.05% of base)
         -49 : System.Private.Uri.dasm (-0.06% of base)
         -49 : System.Net.Primitives.dasm (-0.07% of base)
         -36 : System.Private.CoreLib.dasm (-0.00% of base)
          -2 : Microsoft.CodeAnalysis.CSharp.dasm (-0.00% of base)

12 total files with Code Size differences (6 improved, 6 regressed), 258 unchanged.

Top method regressions (bytes):
         102 (10.11% of base) : FSharp.Core.dasm - HashCompare:GenericEqualityArbArray(bool,System.Collections.IEqualityComparer,System.Array,System.Array):bool
          72 ( 0.45% of base) : System.Net.Http.dasm - <SendAsyncCore>d__56:MoveNext():this
          71 ( 6.32% of base) : FSharp.Core.dasm - HashCompare:GenericComparisonArbArrayWithComparer(GenericComparer,System.Array,System.Array):int
          50 ( 8.55% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.Domain:CreateLocalSideOfTrustRelationship(System.String,int,System.String):this
          50 ( 8.47% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.Forest:CreateLocalSideOfTrustRelationship(System.String,int,System.String):this
          49 (33.56% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.DirectoryContext:isCurrentForest():bool:this
          46 (12.11% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.ActiveDirectorySite:GetComputerSite():System.DirectoryServices.ActiveDirectory.ActiveDirectorySite
          32 ( 0.74% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.Rss20FeedFormatter:ReadItemFrom(System.Xml.XmlReader,System.ServiceModel.Syndication.SyndicationItem,System.Uri):this
          24 (29.27% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateAlternateLink(System.Uri,System.String):System.ServiceModel.Syndication.SyndicationLink
          24 (29.27% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateSelfLink(System.Uri,System.String):System.ServiceModel.Syndication.SyndicationLink
          20 ( 9.66% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:AddPermalink(System.Uri):this
          16 ( 5.26% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationFeed:.ctor(System.String,System.String,System.Uri,System.String,System.DateTimeOffset,System.Collections.Generic.IEnumerable`1[[System.ServiceModel.Syndication.SyndicationItem, System.ServiceModel.Syndication, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51]]):this
          16 ( 6.50% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:.ctor(System.String,System.ServiceModel.Syndication.SyndicationContent,System.Uri,System.String,System.DateTimeOffset):this
          16 (20.78% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateAlternateLink(System.Uri):System.ServiceModel.Syndication.SyndicationLink
          16 (20.78% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateSelfLink(System.Uri):System.ServiceModel.Syndication.SyndicationLink
          12 ( 0.76% of base) : System.Data.Odbc.dasm - System.Data.Odbc.OdbcDataReader:GetBytesOrChars(int,long,System.Array,bool,int,int):long:this
          10 ( 6.62% of base) : System.Private.DataContractSerialization.dasm - System.Xml.ValueHandle:ToULong():long:this
          10 ( 1.33% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationFeed:TryReadTextInputFromExtension(System.ServiceModel.Syndication.SyndicationElementExtensionCollection):System.ServiceModel.Syndication.SyndicationTextInput:this
           8 ( 4.10% of base) : System.Private.CoreLib.dasm - System.Enum:ToUInt64():long:this
           8 (25.81% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:.ctor(System.Uri):this

Top method improvements (bytes):
        -478 (-3.37% of base) : System.Formats.Asn1.dasm - System.Formats.Asn1.AsnWriter:WriteGeneralizedTimeCore(System.Formats.Asn1.Asn1Tag,System.DateTimeOffset,bool):this
         -49 (-6.67% of base) : System.Private.Uri.dasm - System.IPv4AddressHelper:ParseNonCanonical(long,int,byref,bool):long
         -49 (-4.16% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Vector`1][System.Numerics.Vector`1[System.Single]]:TryReadTo(byref,System.ReadOnlySpan`1[Vector`1],bool):bool:this (2 methods)
         -49 (-6.67% of base) : System.Net.Primitives.dasm - System.IPv4AddressHelper:ParseNonCanonical(long,int,byref,bool):long
         -34 (-0.35% of base) : System.Formats.Asn1.dasm - System.Formats.Asn1.AsnWriter:WriteUtcTimeCore(System.Formats.Asn1.Asn1Tag,System.DateTimeOffset):this
         -23 (-2.06% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Byte][System.Byte]:TryReadTo(byref,System.ReadOnlySpan`1[Byte],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Int16][System.Int16]:TryReadTo(byref,System.ReadOnlySpan`1[Int16],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Int32][System.Int32]:TryReadTo(byref,System.ReadOnlySpan`1[Int32],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Double][System.Double]:TryReadTo(byref,System.ReadOnlySpan`1[Double],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Int64][System.Int64]:TryReadTo(byref,System.ReadOnlySpan`1[Int64],bool):bool:this (2 methods)
         -22 (-17.19% of base) : System.Private.CoreLib.dasm - System.Convert:ToDateTime(System.String):System.DateTime
         -22 (-16.06% of base) : System.Private.CoreLib.dasm - System.Convert:ToDateTime(System.String,System.IFormatProvider):System.DateTime
         -10 (-16.67% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationFeed:CreateLink():System.ServiceModel.Syndication.SyndicationLink:this
         -10 (-16.67% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:CreateLink():System.ServiceModel.Syndication.SyndicationLink:this
          -6 (-18.18% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:.ctor():this
          -3 (-1.35% of base) : System.Net.Http.dasm - System.Net.Http.FailedProxyCache:GetProxyRenewTicks(System.Uri):long:this
          -2 (-0.16% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.Rss20FeedFormatter:ReadMediaEnclosure(System.Xml.XmlReader,System.Uri):System.ServiceModel.Syndication.SyndicationLink:this
          -2 (-0.28% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.Rss20FeedFormatter:ReadAlternateLink(System.Xml.XmlReader,System.Uri,System.ServiceModel.Syndication.TryParseUriCallback,bool):System.ServiceModel.Syndication.SyndicationLink
          -1 (-0.22% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.DiagnosticsPass:FindSurprisingSignExtensionBits(Microsoft.CodeAnalysis.CSharp.BoundExpression):long
          -1 (-0.13% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.CodeGen.CodeGenerator:EmitArrayIndices(System.Collections.Immutable.ImmutableArray`1[[Microsoft.CodeAnalysis.CSharp.BoundExpression, Microsoft.CodeAnalysis.CSharp, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]):this

Top method regressions (percentages):
          49 (33.56% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.DirectoryContext:isCurrentForest():bool:this
          24 (29.27% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateAlternateLink(System.Uri,System.String):System.ServiceModel.Syndication.SyndicationLink
          24 (29.27% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateSelfLink(System.Uri,System.String):System.ServiceModel.Syndication.SyndicationLink
           8 (25.81% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:.ctor(System.Uri):this
          16 (20.78% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateAlternateLink(System.Uri):System.ServiceModel.Syndication.SyndicationLink
          16 (20.78% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateSelfLink(System.Uri):System.ServiceModel.Syndication.SyndicationLink
          46 (12.11% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.ActiveDirectorySite:GetComputerSite():System.DirectoryServices.ActiveDirectory.ActiveDirectorySite
         102 (10.11% of base) : FSharp.Core.dasm - HashCompare:GenericEqualityArbArray(bool,System.Collections.IEqualityComparer,System.Array,System.Array):bool
          20 ( 9.66% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:AddPermalink(System.Uri):this
          50 ( 8.55% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.Domain:CreateLocalSideOfTrustRelationship(System.String,int,System.String):this
          50 ( 8.47% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.Forest:CreateLocalSideOfTrustRelationship(System.String,int,System.String):this
          10 ( 6.62% of base) : System.Private.DataContractSerialization.dasm - System.Xml.ValueHandle:ToULong():long:this
          16 ( 6.50% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:.ctor(System.String,System.ServiceModel.Syndication.SyndicationContent,System.Uri,System.String,System.DateTimeOffset):this
          71 ( 6.32% of base) : FSharp.Core.dasm - HashCompare:GenericComparisonArbArrayWithComparer(GenericComparer,System.Array,System.Array):int
          16 ( 5.26% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationFeed:.ctor(System.String,System.String,System.Uri,System.String,System.DateTimeOffset,System.Collections.Generic.IEnumerable`1[[System.ServiceModel.Syndication.SyndicationItem, System.ServiceModel.Syndication, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51]]):this
           8 ( 4.10% of base) : System.Private.CoreLib.dasm - System.Enum:ToUInt64():long:this
           5 ( 3.33% of base) : FSharp.Core.dasm - OperatorIntrinsics:loop@5442-8(long,int):long
           5 ( 3.18% of base) : FSharp.Core.dasm - OperatorIntrinsics:loop@5442-7(long,int):long
           7 ( 2.38% of base) : System.Private.DataContractSerialization.dasm - System.Xml.XmlBinaryNodeWriter:WriteStartElement(System.String,System.String):this
           6 ( 2.01% of base) : System.Private.DataContractSerialization.dasm - System.Xml.ValueHandle:ToLong():long:this

Top method improvements (percentages):
          -6 (-18.18% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:.ctor():this
         -22 (-17.19% of base) : System.Private.CoreLib.dasm - System.Convert:ToDateTime(System.String):System.DateTime
         -10 (-16.67% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationFeed:CreateLink():System.ServiceModel.Syndication.SyndicationLink:this
         -10 (-16.67% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:CreateLink():System.ServiceModel.Syndication.SyndicationLink:this
         -22 (-16.06% of base) : System.Private.CoreLib.dasm - System.Convert:ToDateTime(System.String,System.IFormatProvider):System.DateTime
         -49 (-6.67% of base) : System.Private.Uri.dasm - System.IPv4AddressHelper:ParseNonCanonical(long,int,byref,bool):long
         -49 (-6.67% of base) : System.Net.Primitives.dasm - System.IPv4AddressHelper:ParseNonCanonical(long,int,byref,bool):long
         -49 (-4.16% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Vector`1][System.Numerics.Vector`1[System.Single]]:TryReadTo(byref,System.ReadOnlySpan`1[Vector`1],bool):bool:this (2 methods)
        -478 (-3.37% of base) : System.Formats.Asn1.dasm - System.Formats.Asn1.AsnWriter:WriteGeneralizedTimeCore(System.Formats.Asn1.Asn1Tag,System.DateTimeOffset,bool):this
         -23 (-2.06% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Byte][System.Byte]:TryReadTo(byref,System.ReadOnlySpan`1[Byte],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Double][System.Double]:TryReadTo(byref,System.ReadOnlySpan`1[Double],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Int16][System.Int16]:TryReadTo(byref,System.ReadOnlySpan`1[Int16],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Int32][System.Int32]:TryReadTo(byref,System.ReadOnlySpan`1[Int32],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Int64][System.Int64]:TryReadTo(byref,System.ReadOnlySpan`1[Int64],bool):bool:this (2 methods)
          -3 (-1.35% of base) : System.Net.Http.dasm - System.Net.Http.FailedProxyCache:GetProxyRenewTicks(System.Uri):long:this
         -34 (-0.35% of base) : System.Formats.Asn1.dasm - System.Formats.Asn1.AsnWriter:WriteUtcTimeCore(System.Formats.Asn1.Asn1Tag,System.DateTimeOffset):this
          -2 (-0.28% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.Rss20FeedFormatter:ReadAlternateLink(System.Xml.XmlReader,System.Uri,System.ServiceModel.Syndication.TryParseUriCallback,bool):System.ServiceModel.Syndication.SyndicationLink
          -1 (-0.22% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.DiagnosticsPass:FindSurprisingSignExtensionBits(Microsoft.CodeAnalysis.CSharp.BoundExpression):long
          -2 (-0.16% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.Rss20FeedFormatter:ReadMediaEnclosure(System.Xml.XmlReader,System.Uri):System.ServiceModel.Syndication.SyndicationLink:this
          -1 (-0.13% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.CodeGen.CodeGenerator:EmitArrayIndices(System.Collections.Immutable.ImmutableArray`1[[Microsoft.CodeAnalysis.CSharp.BoundExpression, Microsoft.CodeAnalysis.CSharp, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]):this

45 total methods with Code Size differences (20 improved, 25 regressed), 345423 unchanged.
PMI with "--cctors"
PMI CodeSize Diffs for System.Private.CoreLib.dll, framework assemblies [invoking .cctors] for  default jit

Summary of Code Size diffs:
(Lower is better)

Total bytes of base: 51377155
Total bytes of diff: 51377082
Total bytes of delta: -73 (-0.00% of base)
    diff is an improvement.

Total byte diff includes 103 bytes from reconciling methods
        Base had    0 unique methods,        0 unique bytes
        Diff had    1 unique methods,      103 unique bytes

Top file regressions (bytes):
         195 : System.DirectoryServices.dasm (0.05% of base)
         183 : FSharp.Core.dasm (0.01% of base)
         152 : System.ServiceModel.Syndication.dasm (0.11% of base)
         103 : Microsoft.CodeAnalysis.dasm (0.01% of base)
          69 : System.Net.Http.dasm (0.01% of base)
          23 : System.Private.DataContractSerialization.dasm (0.00% of base)
          14 : System.Data.Odbc.dasm (0.01% of base)

Top file improvements (bytes):
        -512 : System.Formats.Asn1.dasm (-0.47% of base)
        -164 : System.Memory.dasm (-0.05% of base)
         -49 : System.Private.Uri.dasm (-0.06% of base)
         -49 : System.Net.Primitives.dasm (-0.07% of base)
         -36 : System.Private.CoreLib.dasm (-0.00% of base)
          -2 : Microsoft.CodeAnalysis.CSharp.dasm (-0.00% of base)

13 total files with Code Size differences (6 improved, 7 regressed), 257 unchanged.

Top method regressions (bytes):
         103 (     ? of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.SmallDictionary`2[__Canon,TargetScope][System.__Canon,Microsoft.CodeAnalysis.Diagnostics.SuppressMessageAttributeState+TargetScope]:RightComplex(AvlNode[__Canon,TargetScope]):AvlNode[__Canon,TargetScope] (0 base, 1 diff methods)
         102 (10.11% of base) : FSharp.Core.dasm - HashCompare:GenericEqualityArbArray(bool,System.Collections.IEqualityComparer,System.Array,System.Array):bool
          72 ( 0.46% of base) : System.Net.Http.dasm - <SendAsyncCore>d__56:MoveNext():this
          71 ( 6.32% of base) : FSharp.Core.dasm - HashCompare:GenericComparisonArbArrayWithComparer(GenericComparer,System.Array,System.Array):int
          50 ( 8.55% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.Domain:CreateLocalSideOfTrustRelationship(System.String,int,System.String):this
          50 ( 8.47% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.Forest:CreateLocalSideOfTrustRelationship(System.String,int,System.String):this
          49 (33.56% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.DirectoryContext:isCurrentForest():bool:this
          46 (12.11% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.ActiveDirectorySite:GetComputerSite():System.DirectoryServices.ActiveDirectory.ActiveDirectorySite
          32 ( 0.74% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.Rss20FeedFormatter:ReadItemFrom(System.Xml.XmlReader,System.ServiceModel.Syndication.SyndicationItem,System.Uri):this
          24 (29.27% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateAlternateLink(System.Uri,System.String):System.ServiceModel.Syndication.SyndicationLink
          24 (29.27% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateSelfLink(System.Uri,System.String):System.ServiceModel.Syndication.SyndicationLink
          20 ( 9.66% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:AddPermalink(System.Uri):this
          16 ( 5.26% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationFeed:.ctor(System.String,System.String,System.Uri,System.String,System.DateTimeOffset,System.Collections.Generic.IEnumerable`1[[System.ServiceModel.Syndication.SyndicationItem, System.ServiceModel.Syndication, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51]]):this
          16 ( 6.50% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:.ctor(System.String,System.ServiceModel.Syndication.SyndicationContent,System.Uri,System.String,System.DateTimeOffset):this
          16 (20.78% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateAlternateLink(System.Uri):System.ServiceModel.Syndication.SyndicationLink
          16 (20.78% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateSelfLink(System.Uri):System.ServiceModel.Syndication.SyndicationLink
          12 ( 0.76% of base) : System.Data.Odbc.dasm - System.Data.Odbc.OdbcDataReader:GetBytesOrChars(int,long,System.Array,bool,int,int):long:this
          10 ( 1.33% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationFeed:TryReadTextInputFromExtension(System.ServiceModel.Syndication.SyndicationElementExtensionCollection):System.ServiceModel.Syndication.SyndicationTextInput:this
          10 ( 6.62% of base) : System.Private.DataContractSerialization.dasm - System.Xml.ValueHandle:ToULong():long:this
           8 (25.81% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:.ctor(System.Uri):this

Top method improvements (bytes):
        -478 (-3.37% of base) : System.Formats.Asn1.dasm - System.Formats.Asn1.AsnWriter:WriteGeneralizedTimeCore(System.Formats.Asn1.Asn1Tag,System.DateTimeOffset,bool):this
         -49 (-6.67% of base) : System.Private.Uri.dasm - System.IPv4AddressHelper:ParseNonCanonical(long,int,byref,bool):long
         -49 (-4.16% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Vector`1][System.Numerics.Vector`1[System.Single]]:TryReadTo(byref,System.ReadOnlySpan`1[Vector`1],bool):bool:this (2 methods)
         -49 (-6.67% of base) : System.Net.Primitives.dasm - System.IPv4AddressHelper:ParseNonCanonical(long,int,byref,bool):long
         -34 (-0.35% of base) : System.Formats.Asn1.dasm - System.Formats.Asn1.AsnWriter:WriteUtcTimeCore(System.Formats.Asn1.Asn1Tag,System.DateTimeOffset):this
         -23 (-2.06% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Byte][System.Byte]:TryReadTo(byref,System.ReadOnlySpan`1[Byte],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Int16][System.Int16]:TryReadTo(byref,System.ReadOnlySpan`1[Int16],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Int32][System.Int32]:TryReadTo(byref,System.ReadOnlySpan`1[Int32],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Double][System.Double]:TryReadTo(byref,System.ReadOnlySpan`1[Double],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Int64][System.Int64]:TryReadTo(byref,System.ReadOnlySpan`1[Int64],bool):bool:this (2 methods)
         -22 (-17.19% of base) : System.Private.CoreLib.dasm - System.Convert:ToDateTime(System.String):System.DateTime
         -22 (-16.06% of base) : System.Private.CoreLib.dasm - System.Convert:ToDateTime(System.String,System.IFormatProvider):System.DateTime
         -10 (-16.67% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationFeed:CreateLink():System.ServiceModel.Syndication.SyndicationLink:this
         -10 (-16.67% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:CreateLink():System.ServiceModel.Syndication.SyndicationLink:this
          -6 (-18.18% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:.ctor():this
          -3 (-1.35% of base) : System.Net.Http.dasm - System.Net.Http.FailedProxyCache:GetProxyRenewTicks(System.Uri):long:this
          -2 (-0.16% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.Rss20FeedFormatter:ReadMediaEnclosure(System.Xml.XmlReader,System.Uri):System.ServiceModel.Syndication.SyndicationLink:this
          -2 (-0.28% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.Rss20FeedFormatter:ReadAlternateLink(System.Xml.XmlReader,System.Uri,System.ServiceModel.Syndication.TryParseUriCallback,bool):System.ServiceModel.Syndication.SyndicationLink
          -1 (-0.22% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.DiagnosticsPass:FindSurprisingSignExtensionBits(Microsoft.CodeAnalysis.CSharp.BoundExpression):long
          -1 (-0.13% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.CodeGen.CodeGenerator:EmitArrayIndices(System.Collections.Immutable.ImmutableArray`1[[Microsoft.CodeAnalysis.CSharp.BoundExpression, Microsoft.CodeAnalysis.CSharp, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]):this

Top method regressions (percentages):
         103 (     ? of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.SmallDictionary`2[__Canon,TargetScope][System.__Canon,Microsoft.CodeAnalysis.Diagnostics.SuppressMessageAttributeState+TargetScope]:RightComplex(AvlNode[__Canon,TargetScope]):AvlNode[__Canon,TargetScope] (0 base, 1 diff methods)
          49 (33.56% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.DirectoryContext:isCurrentForest():bool:this
          24 (29.27% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateAlternateLink(System.Uri,System.String):System.ServiceModel.Syndication.SyndicationLink
          24 (29.27% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateSelfLink(System.Uri,System.String):System.ServiceModel.Syndication.SyndicationLink
           8 (25.81% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:.ctor(System.Uri):this
          16 (20.78% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateAlternateLink(System.Uri):System.ServiceModel.Syndication.SyndicationLink
          16 (20.78% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:CreateSelfLink(System.Uri):System.ServiceModel.Syndication.SyndicationLink
          46 (12.11% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.ActiveDirectorySite:GetComputerSite():System.DirectoryServices.ActiveDirectory.ActiveDirectorySite
         102 (10.11% of base) : FSharp.Core.dasm - HashCompare:GenericEqualityArbArray(bool,System.Collections.IEqualityComparer,System.Array,System.Array):bool
          20 ( 9.66% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:AddPermalink(System.Uri):this
          50 ( 8.55% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.Domain:CreateLocalSideOfTrustRelationship(System.String,int,System.String):this
          50 ( 8.47% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.Forest:CreateLocalSideOfTrustRelationship(System.String,int,System.String):this
          10 ( 6.62% of base) : System.Private.DataContractSerialization.dasm - System.Xml.ValueHandle:ToULong():long:this
          16 ( 6.50% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:.ctor(System.String,System.ServiceModel.Syndication.SyndicationContent,System.Uri,System.String,System.DateTimeOffset):this
          71 ( 6.32% of base) : FSharp.Core.dasm - HashCompare:GenericComparisonArbArrayWithComparer(GenericComparer,System.Array,System.Array):int
          16 ( 5.26% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationFeed:.ctor(System.String,System.String,System.Uri,System.String,System.DateTimeOffset,System.Collections.Generic.IEnumerable`1[[System.ServiceModel.Syndication.SyndicationItem, System.ServiceModel.Syndication, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51]]):this
           8 ( 4.10% of base) : System.Private.CoreLib.dasm - System.Enum:ToUInt64():long:this
           5 ( 3.33% of base) : FSharp.Core.dasm - OperatorIntrinsics:loop@5442-8(long,int):long
           5 ( 3.18% of base) : FSharp.Core.dasm - OperatorIntrinsics:loop@5442-7(long,int):long
           7 ( 2.38% of base) : System.Private.DataContractSerialization.dasm - System.Xml.XmlBinaryNodeWriter:WriteStartElement(System.String,System.String):this

Top method improvements (percentages):
          -6 (-18.18% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationLink:.ctor():this
         -22 (-17.19% of base) : System.Private.CoreLib.dasm - System.Convert:ToDateTime(System.String):System.DateTime
         -10 (-16.67% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationFeed:CreateLink():System.ServiceModel.Syndication.SyndicationLink:this
         -10 (-16.67% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.SyndicationItem:CreateLink():System.ServiceModel.Syndication.SyndicationLink:this
         -22 (-16.06% of base) : System.Private.CoreLib.dasm - System.Convert:ToDateTime(System.String,System.IFormatProvider):System.DateTime
         -49 (-6.67% of base) : System.Private.Uri.dasm - System.IPv4AddressHelper:ParseNonCanonical(long,int,byref,bool):long
         -49 (-6.67% of base) : System.Net.Primitives.dasm - System.IPv4AddressHelper:ParseNonCanonical(long,int,byref,bool):long
         -49 (-4.16% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Vector`1][System.Numerics.Vector`1[System.Single]]:TryReadTo(byref,System.ReadOnlySpan`1[Vector`1],bool):bool:this (2 methods)
        -478 (-3.37% of base) : System.Formats.Asn1.dasm - System.Formats.Asn1.AsnWriter:WriteGeneralizedTimeCore(System.Formats.Asn1.Asn1Tag,System.DateTimeOffset,bool):this
         -23 (-2.06% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Byte][System.Byte]:TryReadTo(byref,System.ReadOnlySpan`1[Byte],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Double][System.Double]:TryReadTo(byref,System.ReadOnlySpan`1[Double],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Int16][System.Int16]:TryReadTo(byref,System.ReadOnlySpan`1[Int16],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Int32][System.Int32]:TryReadTo(byref,System.ReadOnlySpan`1[Int32],bool):bool:this (2 methods)
         -23 (-2.05% of base) : System.Memory.dasm - System.Buffers.SequenceReader`1[Int64][System.Int64]:TryReadTo(byref,System.ReadOnlySpan`1[Int64],bool):bool:this (2 methods)
          -3 (-1.35% of base) : System.Net.Http.dasm - System.Net.Http.FailedProxyCache:GetProxyRenewTicks(System.Uri):long:this
         -34 (-0.35% of base) : System.Formats.Asn1.dasm - System.Formats.Asn1.AsnWriter:WriteUtcTimeCore(System.Formats.Asn1.Asn1Tag,System.DateTimeOffset):this
          -2 (-0.28% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.Rss20FeedFormatter:ReadAlternateLink(System.Xml.XmlReader,System.Uri,System.ServiceModel.Syndication.TryParseUriCallback,bool):System.ServiceModel.Syndication.SyndicationLink
          -1 (-0.22% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.DiagnosticsPass:FindSurprisingSignExtensionBits(Microsoft.CodeAnalysis.CSharp.BoundExpression):long
          -2 (-0.16% of base) : System.ServiceModel.Syndication.dasm - System.ServiceModel.Syndication.Rss20FeedFormatter:ReadMediaEnclosure(System.Xml.XmlReader,System.Uri):System.ServiceModel.Syndication.SyndicationLink:this
          -1 (-0.13% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.CodeGen.CodeGenerator:EmitArrayIndices(System.Collections.Immutable.ImmutableArray`1[[Microsoft.CodeAnalysis.CSharp.BoundExpression, Microsoft.CodeAnalysis.CSharp, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]):this

46 total methods with Code Size differences (20 improved, 26 regressed), 345681 unchanged.

@kunalspathak
Copy link
Member

Seeing as the CI is green, posting the final diffs:

Did you get chance to see why there are regressions?

@SingleAccretion
Copy link
Contributor Author

SingleAccretion commented Jan 21, 2021

Did you get chance to see why there are regressions?

Right, the regressions. I haven't studied a lot in detail yet, but so far it seems like more inlining causing more code to be generated. I will update this post as I analyze more cases.

HashCompare:GenericEqualityArbArray(bool,System.Collections.IEqualityComparer,System.Array,System.Array):bool - diff
The essential difference here is that HashCompare:check@1369-2(bool,System.Collections.IEqualityComparer,System.Array,System.Array,long,long,long,long):bool gets inlined. This actually doesn't look so bad as it has a large prologue:

HashCompare:check
G_M62082_IG01:
       push     r15
       push     r14
       push     r13
       push     r12
       push     rdi
       push     rsi
       push     rbp
       push     rbx
       sub      rsp, 40
       mov      r14d, ecx
       mov      rbp, rdx
       mov      rdi, r8
       mov      rbx, r9
       mov      r15, qword ptr [rsp+90H]
       mov      r12, qword ptr [rsp+98H]
       mov      r13, qword ptr [rsp+A0H]
       mov      rsi, qword ptr [rsp+A8H]
						;; bbWeight=1    PerfScore 13.25
G_M62082_IG02:
       cmp      rsi, r15
       jl       SHORT G_M62082_IG05
						;; bbWeight=8    PerfScore 10.00
G_M62082_IG03:
       mov      eax, 1
						;; bbWeight=0.50 PerfScore 0.12
G_M62082_IG04:
       add      rsp, 40
       pop      rbx
       pop      rbp
       pop      rsi
       pop      rdi
       pop      r12
       pop      r13
       pop      r14
       pop      r15
       ret      
						;; bbWeight=0.50 PerfScore 2.62
G_M62082_IG05:
       lea      rcx, [r12+rsi]
       cmp      dword ptr [rdi], edi
       mov      edx, ecx
       movsxd   rax, edx
       cmp      rcx, rax
       jne      SHORT G_M62082_IG10
						;; bbWeight=4    PerfScore 17.00
G_M62082_IG06:
       mov      rcx, rdi
       call     System.Array:GetValue(int):System.Object:this
       mov      gword ptr [rsp+20H], rax
       lea      rcx, [rsi+r13]
       cmp      dword ptr [rbx], ebx
       mov      edx, ecx
       movsxd   r8, edx
       cmp      rcx, r8
       jne      SHORT G_M62082_IG10
						;; bbWeight=4    PerfScore 26.00
G_M62082_IG07:
       mov      rcx, rbx
       call     System.Array:GetValue(int):System.Object:this
       mov      r9, rax
       movzx    rcx, r14b
       mov      rdx, rbp
       mov      r8, gword ptr [rsp+20H]
       call     HashCompare:GenericEqualityObj(bool,System.Collections.IEqualityComparer,System.Object,System.Object):bool
       test     eax, eax
       je       SHORT G_M62082_IG08
       inc      rsi
       jmp      SHORT G_M62082_IG02
						;; bbWeight=4    PerfScore 30.00
G_M62082_IG08:
       xor      eax, eax
						;; bbWeight=0.50 PerfScore 0.12
G_M62082_IG09:
       add      rsp, 40
       pop      rbx
       pop      rbp
       pop      rsi
       pop      rdi
       pop      r12
       pop      r13
       pop      r14
       pop      r15
       ret      
						;; bbWeight=0.50 PerfScore 2.62
G_M62082_IG10:
       mov      ecx, 21
       mov      edx, 50
       call     System.ThrowHelper:ThrowArgumentOutOfRangeException(int,int)
       int3     

; Total bytes of code 204, prolog size 16, PerfScore 122.15, instruction count 71, allocated bytes for code 204 (MethodHash=38330d7d) for method HashCompare:check@1369-2(bool,System.Collections.IEqualityComparer,System.Array,System.Array,long,long,long,long):bool
; ============================================================

This is also the case for HashCompare:GenericComparisonArbArrayWithComparer(GenericComparer,System.Array,System.Array):int - diff.

System.DirectoryServices.ActiveDirectory.DirectoryContext:isCurrentForest():bool:this - diff
In this case, System.DirectoryServices.ActiveDirectory.Locator:GetDomainControllerInfo(System.String,System.String,System.String,long):System.DirectoryServices.ActiveDirectory.DomainControllerInfo gets inlined, which introduced some shuffling of things around. The inlined method looks like a simple validating wrapper:

internal static DomainControllerInfo GetDomainControllerInfo(string computerName, string domainName, string siteName, long flags)
{
int errorCode = 0;
DomainControllerInfo domainControllerInfo;
errorCode = DsGetDcNameWrapper(computerName, domainName, siteName, flags, out domainControllerInfo);
if (errorCode != 0)
{
throw ExceptionHelper.GetExceptionFromErrorCode(errorCode, domainName);
}
return domainControllerInfo;
}

All the following regressions are also caused by inlining of this method:
ActiveDirectorySite:GetComputerSite():System.DirectoryServices.ActiveDirectory.ActiveDirectorySite - diff
Domain:CreateLocalSideOfTrustRelationship(System.String,int,System.String):this - diff
Forest:CreateLocalSideOfTrustRelationship(System.String,int,System.String):this - diff

System.ServiceModel.Syndication.SyndicationLink:CreateAlternateLink(System.Uri,System.String):System.ServiceModel.Syndication.SyndicationLink - diff
In this case, SyndicationLink's constructor is being inlined, which to my my untrained eye seems unnecessary:

public SyndicationLink(Uri uri, string relationshipType, string title, string mediaType, long length)
{
if (length < 0)
{
throw new ArgumentOutOfRangeException(nameof(length));
}
BaseUri = null;
Uri = uri;
Title = title;
RelationshipType = relationshipType;
MediaType = mediaType;
_length = length;
}

However, it does eliminate the exception throw and presumably avoids prefetching all the cold code.

SyndicationLink constructor
G_M54833_IG01:
       push     rdi
       push     rsi
       push     rbp
       push     rbx
       sub      rsp, 40
       mov      rsi, rcx
       mov      rdi, r8
       mov      rbx, r9
       mov      rbp, qword ptr [rsp+78H]
						;; bbWeight=1    PerfScore 6.00
G_M54833_IG02:
       test     rbp, rbp
       jl       SHORT G_M54833_IG05
						;; bbWeight=1    PerfScore 1.25
G_M54833_IG03:
       xor      rcx, rcx
       mov      gword ptr [rsi+8], rcx
       lea      rcx, bword ptr [rsi+40]
       call     CORINFO_HELP_ASSIGN_REF
       lea      rcx, bword ptr [rsi+32]
       mov      rdx, rbx
       call     CORINFO_HELP_ASSIGN_REF
       lea      rcx, bword ptr [rsi+24]
       mov      rdx, rdi
       call     CORINFO_HELP_ASSIGN_REF
       lea      rcx, bword ptr [rsi+16]
       mov      rdx, gword ptr [rsp+70H]
       call     CORINFO_HELP_ASSIGN_REF
       mov      qword ptr [rsi+48], rbp
						;; bbWeight=1    PerfScore 9.75
G_M54833_IG04:
       add      rsp, 40
       pop      rbx
       pop      rbp
       pop      rsi
       pop      rdi
       ret      
						;; bbWeight=1    PerfScore 3.25
G_M54833_IG05:
       mov      rcx, 0xD1FFAB1E
       call     CORINFO_HELP_NEWSFAST
       mov      rsi, rax
       mov      ecx, 0xAC7
       mov      rdx, 0xD1FFAB1E
       call     CORINFO_HELP_STRCNS
       mov      rdx, rax
       mov      rcx, rsi
       call     System.ArgumentOutOfRangeException:.ctor(System.String):this
       mov      rcx, rsi
       call     CORINFO_HELP_THROW
       int3     
						;; bbWeight=0    PerfScore 0.00

; Total bytes of code 151, prolog size 8, PerfScore 35.35, instruction count 43, allocated bytes for code 151 (MethodHash=395929ce) for method System.ServiceModel.Syndication.SyndicationLink:.ctor(System.Uri,System.String,System.String,System.String,long):this
; ============================================================

All the following regressions are also caused by inlining of this constructor:
SyndicationLink:CreateSelfLink(System.Uri,System.String):SyndicationLink - diff
SyndicationItem:.ctor(System.String,SyndicationContent,System.Uri,System.String,System.DateTimeOffset):this - diff
SyndicationLink:.ctor(System.Uri):this - diff
SyndicationLink:CreateAlternateLink(System.Uri):SyndicationLink - diff
SyndicationLink:CreateSelfLink(System.Uri):SyndicationLink - diff
SyndicationItem:.ctor(System.String,SyndicationContent,System.Uri,System.String,System.DateTimeOffset):this - diff
SyndicationFeed:.ctor(System.String,System.String,System.Uri,System.String,System.DateTimeOffset,IEnumerable):this - diff

System.Enum:ToUInt64():long:this - diff
System.Xml.ValueHandle:ToULong():long:this - diff
OperatorIntrinsics:loop@5442-8(long,int):long- diff
OperatorIntrinsics:loop@5442-7(long,int):long - diff
These are some interesting regressions. Would have to get a dump to understand why are the new returns being created. Investigation complete, see below.

System.Xml.XmlBinaryNodeWriter:WriteStartElement(System.String,System.String):this - diff
Looks like some interesting CSE hiccup.
Investigation complete, see below.

@SingleAccretion
Copy link
Contributor Author

SingleAccretion commented Jan 22, 2021

So, the regressions due to the new returns being created are caused by the fact that MergedReturns.Merge recognizes constant returns and creates dedicated blocks for them, more or less by design:

// We have a constant. Now find or create a corresponding return block.

The limit on the number of returns created is constant right now:

// We currently apply a hard limit of '4' to all other targets (see
// the other uses of SET_EPILOGCNT_MAX), though it would be good
// to revisit that decision based on CQ analysis.
const static unsigned ReturnCountHardLimit = 4;

This means that returns for constants are created "eagerly". A sample that demonstrates this behavior: sharplab.

While this logic could be improved, my changes just exposed this behavior, and working on an item this large is out of my reach at this point anyway.

@kunalspathak
Copy link
Member

While this logic could be improved, my changes just exposed this behavior, and working on an item this large is out of my reach at this point anyway.

Thank you @SingleAccretion for the analysis.

@SingleAccretion
Copy link
Contributor Author

System.Xml.XmlBinaryNodeWriter:WriteStartElement(System.String,System.String):this - diff

In this case, we are able to successfully propagate the constants to the inlined callees very early, which lowers the number of local variables and thus CSE chooses to promote the array's length. In doing so, it replaces two defs and one use, which results in the length being loaded from memory twice in the final codegen, kind of defeating the purpose.

CSE section in the dump
Aggressive CSE Promotion cutoff is 200.000000
Moderate CSE Promotion cutoff is 100.000000
enregCount is 12
Framesize estimate is 0x0000
We have a small frame

Sorted CSE candidates:
CSE #02, {$d1 , $4  } useCnt=0: [def=150.000000, use=0.000000, cost=  4      ]
        :: N004 (  4,  4) CSE #02 (def)[000101] ---XG-------              *  IND       int    <l:$d3, c:$fb>
CSE #01, {$100, $140} useCnt=1: [def=75.000000, use=50.000000, cost=  3      ]
        :: N002 (  3,  3) CSE #01 (def)[000060] ---X--------              *  ARR_LENGTH int    $c1

Skipped CSE #02 because use count is 0

Considering CSE #01 {$100, $140} [def=75.000000, use=50.000000, cost=  3      ]
CSE Expression : 
N002 (  3,  3) CSE #01 (def)[000060] ---X--------              *  ARR_LENGTH int    $c1
N001 (  1,  1)              [000059] ------------              \--*  LCL_VAR   ref    V01 arg1         u:1 $81

Aggressive CSE Promotion (200.000000 >= 200.000000)
cseRefCnt=200.000000, aggressiveRefCnt=200.000000, moderateRefCnt=100.000000
defCnt=75.000000, useCnt=50.000000, cost=3, size=3
def_cost=1, use_cost=1, extra_no_cost=4, extra_yes_cost=0
CSE cost savings check (154.000000 >= 125.000000) passes

Promoting CSE:

lvaGrabTemp returning 15 (V15 rat0) (a long lifetime temp) called for CSE - aggressive.
New refCnts for V15: refCnt =  2, refCntWtd = 0.50
New refCnts for V15: refCnt =  3, refCntWtd = 1   
New refCnts for V15: refCnt =  4, refCntWtd = 1.50
New refCnts for V15: refCnt =  5, refCntWtd = 2   

CSE #01 def at [000060] replaced in BB02 with def of V15
optValnumCSE morphed tree:
N009 ( 14, 12)              [000063] -A-X--------              *  JTRUE     void  
N008 ( 12, 10)              [000062] JA-X---N----              \--*  EQ        int    $c3
N006 ( 10,  8)              [000277] -A-X--------                 +--*  COMMA     int    $c1
N004 (  7,  6)              [000275] -A-X----R---                 |  +--*  ASG       int    $VN.Void
N003 (  3,  2)              [000274] D------N----                 |  |  +--*  LCL_VAR   int    V15 cse0          $c1
N002 (  3,  3)              [000060] ---X--------                 |  |  \--*  ARR_LENGTH int    $c1
N001 (  1,  1)              [000059] ------------                 |  |     \--*  LCL_VAR   ref    V01 arg1         u:1 $81
N005 (  3,  2)              [000276] ------------                 |  \--*  LCL_VAR   int    V15 cse0          $c1
N007 (  1,  1)              [000061] ------------                 \--*  CNS_INT   int    0 $40


CSE #01 def at [000215] replaced in BB09 with def of V15
optValnumCSE morphed tree:
N015 ( 24, 24)              [000010] -A-XG---R---              *  ASG       int    <l:$c9, c:$c8>
N014 (  3,  2)              [000009] D------N----              +--*  LCL_VAR   int    V03 loc0         d:1 <l:$c7, c:$c6>
N013 ( 20, 21)              [000222] -A-XG-------              \--*  COMMA     ushort <l:$c5, c:$340>
N008 ( 15, 16)              [000216] -A-X--------                 +--*  ARR_BOUNDS_CHECK_Rng void   $145
N001 (  1,  1)              [000007] ------------                 |  +--*  CNS_INT   int    0 $40
N007 ( 10,  8)              [000281] -A-X--------                 |  \--*  COMMA     int    $c1
N005 (  7,  6)              [000279] -A-X----R---                 |     +--*  ASG       int    $VN.Void
N004 (  3,  2)              [000278] D------N----                 |     |  +--*  LCL_VAR   int    V15 cse0          $c1
N003 (  3,  3)              [000215] ---X--------                 |     |  \--*  ARR_LENGTH int    $c1
N002 (  1,  1)              [000006] ------------                 |     |     \--*  LCL_VAR   ref    V01 arg1         u:1 $81
N006 (  3,  2)              [000280] ------------                 |     \--*  LCL_VAR   int    V15 cse0          $c1
N012 (  5,  5)              [000008] a---G-------                 \--*  IND       ushort <l:$c4, c:$300>
N011 (  2,  2)              [000221] -------N----                    \--*  ADD       byref  $280
N009 (  1,  1)              [000213] ------------                       +--*  LCL_VAR   ref    V01 arg1         u:1 $81
N010 (  1,  1)              [000220] ------------                       \--*  CNS_INT   long   12 Fseq[#FirstElem] $1c0


Working on the replacement of the CSE #01 use at [000012] in BB09
optValnumCSE morphed tree:
N004 (  7,  6)              [000015] ------------              *  JTRUE     void  
N003 (  5,  4)              [000014] N------N-U--              \--*  NE        int    $cb
N001 (  3,  2)              [000282] ------------                 +--*  LCL_VAR   int    V15 cse0          $100
N002 (  1,  1)              [000013] ------------                 \--*  CNS_INT   int    1 $41

I have reduced this to the following method:

public static int Get(string a)
{
    if (string.IsNullOrEmpty(a))
    {
        return 7;
    }
    else
    {
        if (a.Length is 1 || a.Length is 2)
        {
            return 9;
        }
        else
        {
            return 11;
        }
    }
}

Which has the following blocks before CSE:

Basic blocks
-----------------------------------------------------------------------------------------------------------------------------------------
BBnum BBid ref try hnd preds           weight    lp [IL range]     [jump]      [EH region]         [flags]
-----------------------------------------------------------------------------------------------------------------------------------------
BB01 [0000]  1                             1       [000..008)-> BB05 ( cond )                     i label target 
BB02 [0007]  1       BB01                  0.25    [000..001)-> BB05 ( cond )                     i idxlen 
BB03 [0008]  1       BB02                  0.50    [000..001)-> BB07 ( cond )                     i 
BB04 [0011]  1       BB03                  0.50    [???..???)-> BB06 (always)                     internal 
BB05 [0009]  2       BB01,BB02             0.50    [000..001)-> BB07 ( cond )                     i label target 
BB06 [0001]  2       BB04,BB05             0.50    [008..00A)        (return)                     i target 
BB07 [0002]  2       BB03,BB05             0.50    [00A..013)-> BB09 ( cond )                     i label target idxlen 
BB08 [0003]  1       BB07                  0.50    [013..01C)-> BB10 ( cond )                     i idxlen 
BB09 [0004]  2       BB07,BB08             0.50    [01C..01F)        (return)                     i label target 
BB10 [0005]  1       BB08                  0.50    [01F..022)        (return)                     i label target 
-----------------------------------------------------------------------------------------------------------------------------------------

------------ BB01 [000..008) -> BB05 (cond), preds={} succs={BB02,BB05}

***** BB01
STMT00007 (IL 0x000...  ???)
N004 (  5,  5) [000024] ------------              *  JTRUE     void  
N003 (  3,  3) [000023] J------N----              \--*  EQ        int    $c0
N001 (  1,  1) [000000] ------------                 +--*  LCL_VAR   ref    V00 arg0         u:1 $80
N002 (  1,  1) [000022] ------------                 \--*  CNS_INT   ref    null $VN.Null

------------ BB02 [000..001) -> BB05 (cond), preds={BB01} succs={BB03,BB05}

***** BB02
STMT00009 (IL 0x000...  ???)
N005 (  7,  7) [000034] ---X--------              *  JTRUE     void  
N004 (  5,  5) [000033] J--X---N----              \--*  EQ        int    $c3
N002 (  3,  3) [000031] ---X--------                 +--*  ARR_LENGTH int    $c1
N001 (  1,  1) [000030] ------------                 |  \--*  LCL_VAR   ref    V00 arg0         u:1 $80
N003 (  1,  1) [000032] ------------                 \--*  CNS_INT   int    0 $40

------------ BB03 [000..001) -> BB07 (cond), preds={BB02} succs={BB04,BB07}

***** BB03
STMT00010 (IL 0x000...  ???)
N003 (  5,  4) [000038] -A------R---              *  ASG       bool   $40
N002 (  3,  2) [000037] D------N----              +--*  LCL_VAR   int    V02 tmp1         d:2 $40
N001 (  1,  1) [000035] ------------              \--*  CNS_INT   int    0 $40

***** BB03
STMT00011 (IL   ???...  ???)
N004 (  8,  7) [000041] ------------              *  JTRUE     void  
N003 (  6,  5) [000042] J------N----              \--*  EQ        int    $42
N001 (  4,  3) [000043] ------------                 +--*  LCL_VAR   bool   V02 tmp1         u:2 (last use) $40
N002 (  1,  1) [000044] ------------                 \--*  CNS_INT   int    0 $40

------------ BB04 [???..???) -> BB06 (always), preds={BB03} succs={BB06}

------------ BB05 [000..001) -> BB07 (cond), preds={BB01,BB02} succs={BB06,BB07}

***** BB05
STMT00008 (IL 0x000...  ???)
N003 (  5,  4) [000028] -A------R---              *  ASG       bool   $42
N002 (  3,  2) [000027] D------N----              +--*  LCL_VAR   int    V02 tmp1         d:1 $42
N001 (  1,  1) [000025] ------------              \--*  CNS_INT   int    1 $42

***** BB05
STMT00001 (IL   ???...  ???)
N004 (  8,  7) [000005] ------------              *  JTRUE     void  
N003 (  6,  5) [000004] J------N----              \--*  EQ        int    $40
N001 (  4,  3) [000039] ------------                 +--*  LCL_VAR   bool   V02 tmp1         u:1 (last use) $42
N002 (  1,  1) [000003] ------------                 \--*  CNS_INT   int    0 $40

------------ BB06 [008..00A) (return), preds={BB04,BB05} succs={}

***** BB06
STMT00006 (IL 0x008...0x009)
N002 (  2,  2) [000021] ------------              *  RETURN    int    $184
N001 (  1,  1) [000020] ------------              \--*  CNS_INT   int    7 $46

------------ BB07 [00A..013) -> BB09 (cond), preds={BB03,BB05} succs={BB08,BB09}

***** BB07
STMT00002 (IL 0x00A...0x011)
N005 (  7,  7) [000010] ---X--------              *  JTRUE     void  
N004 (  5,  5) [000009] J--X---N----              \--*  EQ        int    $c5
N002 (  3,  3) [000007] ---X--------                 +--*  ARR_LENGTH int    $c1
N001 (  1,  1) [000006] ------------                 |  \--*  LCL_VAR   ref    V00 arg0         u:1 $80
N003 (  1,  1) [000008] ------------                 \--*  CNS_INT   int    1 $42

------------ BB08 [013..01C) -> BB10 (cond), preds={BB07} succs={BB09,BB10}

***** BB08
STMT00004 (IL 0x013...0x01A)
N005 (  7,  7) [000017] ---X--------              *  JTRUE     void  
N004 (  5,  5) [000016] N--X---N-U--              \--*  NE        int    $c7
N002 (  3,  3) [000014] ---X--------                 +--*  ARR_LENGTH int    $c1
N001 (  1,  1) [000013] ------------                 |  \--*  LCL_VAR   ref    V00 arg0         u:1 (last use) $80
N003 (  1,  1) [000015] ------------                 \--*  CNS_INT   int    2 $43

------------ BB09 [01C..01F) (return), preds={BB07,BB08} succs={}

***** BB09
STMT00003 (IL 0x01C...0x01E)
N002 (  2,  2) [000012] ------------              *  RETURN    int    $183
N001 (  1,  1) [000011] ------------              \--*  CNS_INT   int    9 $45

------------ BB10 [01F..022) (return), preds={BB08} succs={}

***** BB10
STMT00005 (IL 0x01F...0x021)
N002 (  2,  2) [000019] ------------              *  RETURN    int    $182
N001 (  1,  1) [000018] ------------              \--*  CNS_INT   int    11 $44

What is important here is that there are blocks left (namely, BB05 and BB03), for which the control flow is "static", but that hasn't been determined yet (the very next phase will do that). BB03 will always jump to BB07 and BB05 never will. Of course, dataflow cannot know that, and correctly computes that BB07 can not have incoming CSEs, because of the BB01 -> BB05 -> BB07 false path, marking a.Length in it as a def, leading to the suboptimal output.

Notably, for this simplistic reproduction CSE is still valuable as it has a use in the a.Length is 2 check, while in the original method the range check (one of the defs) gets eliminated, causing the CSE to appear "out of nowhere".

Overall, it seems to me that things in this case work as they are supposed to, just the unfortunate input causes unfortunate output.

Copy link
Member

@AndyAyersMS AndyAyersMS left a comment

Choose a reason for hiding this comment

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

Looks good.

Thank you for the fix!

@JulieLeeMSFT JulieLeeMSFT added this to the 6.0.0 milestone Feb 23, 2021
@SingleAccretion SingleAccretion deleted the Folding-cast-nodes-for-inlining branch May 1, 2021 17:38
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
Development

Successfully merging this pull request may close these issues.

4 participants