Skip to content

Conversation

@BruceForstall
Copy link
Contributor

Convert x % 2 == 0 to x & 1 == 0 to generate better code.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Dec 2, 2020
@EgorBo
Copy link
Member

EgorBo commented Dec 2, 2020

A few notes:

  1. It can be any power-of-two number, e.g. x % 8 == 0 -> x & 7 == 0
  2. It's probably simpler to just change operator from GT_MOD to GT_UMOD so the lowering will optimize it to AND itself
  3. Afair, it won't work for ARM since it deconstructs % too early.
  4. It's also possible to optimize X % C == 0 for any C, not just power-of-two: https://godbolt.org/z/QvpwEt (benchmark: https://twitter.com/EgorBo/status/1228338329244065798)

@am11
Copy link
Member

am11 commented Dec 3, 2020

(out of curiosity) would it be possible to eliminate the extra movzx via this peephole optimization?

method

bool M(int x)
{
    const int y = 2147483647; // 231 - 1
    return (x & y) == 0;
}

codegen comparison

- clang
+ RyuJIT

-       test    edi, 2147483647
+       test    edx, 2147483647
        sete    al
+       movzx   eax, al
        ret

@BruceForstall
Copy link
Contributor Author

SPMI diffs are pretty small across libraries and tests. A few regressions in tests where we can't CSE a duplicated MOD after morphing one of them.

////// x64 diffs
/// libraries

Found 74 files with textual diffs.

Summary of Code Size diffs:
(Lower is better)

Total bytes of base: 50274
Total bytes of diff: 49260
Total bytes of delta: -1014 (-2.02% of base)
    diff is an improvement.

Top file improvements (bytes):
         -32 : 73939.dasm (-4.40% of base)
         -29 : 189050.dasm (-9.15% of base)
         -20 : 137547.dasm (-5.59% of base)
         -19 : 104206.dasm (-5.59% of base)
         -19 : 168448.dasm (-2.14% of base)
         -19 : 81797.dasm (-5.59% of base)
         -18 : 168588.dasm (-2.30% of base)
         -18 : 195505.dasm (-0.72% of base)
         -18 : 208067.dasm (-2.45% of base)
         -18 : 55171.dasm (-0.63% of base)
         -17 : 137197.dasm (-0.89% of base)
         -16 : 119323.dasm (-1.72% of base)
         -16 : 12416.dasm (-2.10% of base)
         -16 : 137196.dasm (-0.82% of base)
         -16 : 177787.dasm (-2.10% of base)
         -16 : 187682.dasm (-1.53% of base)
         -16 : 218573.dasm (-0.40% of base)
         -16 : 221368.dasm (-1.06% of base)
         -16 : 221410.dasm (-1.27% of base)
         -16 : 221432.dasm (-2.39% of base)

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

Top method improvements (bytes):
         -32 (-4.40% of base) : 73939.dasm - Microsoft.CodeAnalysis.CommandLineParser:SplitCommandLineIntoArguments(System.String,bool,byref):System.Collections.Generic.IEnumerable`1[[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
         -29 (-9.15% of base) : 189050.dasm - System.Diagnostics.EventLogInternal:set_MaximumKilobytes(long):this
         -20 (-5.59% of base) : 137547.dasm - System.Xml.ValueHandle:TryReadBase64(System.Byte[],int,int,byref):bool:this
         -19 (-5.59% of base) : 104206.dasm - Microsoft.Diagnostics.Tracing.EventPipeBlock:FromStream(FastSerialization.Deserializer):this
         -19 (-2.14% of base) : 168448.dasm - ILCompiler.PdbWriter.PdbWriter:WriteFileChecksums():this
         -19 (-5.59% of base) : 81797.dasm - Microsoft.Diagnostics.Tracing.EventPipeBlock:FromStream(FastSerialization.Deserializer):this
         -18 (-2.30% of base) : 168588.dasm - R2RDump.TextDumper:DumpBytes(int,int,System.String,bool):this
         -18 (-0.72% of base) : 195505.dasm - System.Drawing.Icon:Initialize(int,int):this
         -18 (-2.45% of base) : 208067.dasm - System.Net.NetworkInformation.PhysicalAddress:TryParse(System.ReadOnlySpan`1[Char],byref):bool
         -18 (-0.63% of base) : 55171.dasm - Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax.Scanner:ScanDateLiteral(Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax.SyntaxList`1[[Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax.VisualBasicSyntaxNode, Microsoft.CodeAnalysis.VisualBasic, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]):Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax.SyntaxToken:this
         -17 (-0.89% of base) : 137197.dasm - System.Text.Base64Encoding:GetBytes(System.Byte[],int,int,System.Byte[],int):int:this
         -16 (-1.72% of base) : 119323.dasm - Microsoft.Diagnostics.Tracing.Ctf.CtfInteger:Read(System.Byte[],int):System.Object:this
         -16 (-2.10% of base) : 12416.dasm - OperatorIntrinsics:loop@5442-13(System.Decimal,System.Decimal,int):System.Decimal
         -16 (-0.82% of base) : 137196.dasm - System.Text.Base64Encoding:GetBytes(System.Char[],int,int,System.Byte[],int):int:this
         -16 (-2.10% of base) : 177787.dasm - System.Collections.Generic.SortedSet`1[__Canon][System.__Canon]:ConstructRootFromSortedArray(System.__Canon[],int,int,Node[__Canon]):Node[__Canon]
         -16 (-1.53% of base) : 187682.dasm - System.Data.OleDb.OleDbConnectionString:LoadStringFromFileStorage(System.String):System.String
         -16 (-0.40% of base) : 218573.dasm - System.Reflection.Metadata.Ecma335.MetadataBuilder:.ctor(int,int,int,int):this
         -16 (-1.06% of base) : 221368.dasm - System.Security.AccessControl.GenericAce:CreateFromBinaryForm(System.Byte[],int):System.Security.AccessControl.GenericAce
         -16 (-1.27% of base) : 221410.dasm - System.Security.AccessControl.ObjectAce:ParseBinaryForm(System.Byte[],int,byref,byref,byref,byref,byref,byref,byref,byref):bool
         -16 (-2.39% of base) : 221432.dasm - System.Security.AccessControl.RawAcl:SetBinaryForm(System.Byte[],int):this

Top method improvements (percentages):
         -14 (-15.56% of base) : 124179.dasm - System.Data.SqlTypes.SqlDateTime:IsLeapYear(int):bool
         -10 (-15.15% of base) : 231341.dasm - System.Text.RegularExpressions.RegexCharClass:CanEasilyEnumerateSetContents(System.String):bool
         -16 (-14.29% of base) : 226094.dasm - System.Security.Cryptography.SymmetricAlgorithm:set_FeedbackSize(int):this
         -11 (-13.25% of base) : 197677.dasm - System.Formats.Cbor.CborWriter:AdvanceDataItemCounters():this
         -11 (-11.96% of base) : 197600.dasm - System.Formats.Cbor.CborReader:AdvanceDataItemCounters():this
         -13 (-9.63% of base) : 104274.dasm - Microsoft.Diagnostics.Tracing.TraceEvent:EventDataAsString():System.String:this
         -13 (-9.63% of base) : 164747.dasm - Microsoft.Extensions.Logging.LogValuesFormatter:FindBraceIndex(System.String,ushort,int,int):int
         -13 (-9.63% of base) : 81891.dasm - Microsoft.Diagnostics.Tracing.TraceEvent:EventDataAsString():System.String:this
         -29 (-9.15% of base) : 189050.dasm - System.Diagnostics.EventLogInternal:set_MaximumKilobytes(long):this
         -12 (-7.23% of base) : 218434.dasm - System.Reflection.Metadata.Ecma335.MethodBodyStreamEncoder:.ctor(System.Reflection.Metadata.BlobBuilder):this
         -10 (-7.04% of base) : 12402.dasm - OperatorIntrinsics:loop@5442-6(int,int):int
         -12 (-6.86% of base) : 144591.dasm - System.Xml.UTF16Decoder:GetCharCount(System.Byte[],int,int,bool):int:this
         -10 (-6.80% of base) : 12412.dasm - OperatorIntrinsics:loop@5442-11(float,int):float
         -10 (-6.80% of base) : 12414.dasm - OperatorIntrinsics:loop@5442-12(double,int):double
         -10 (-6.71% of base) : 12524.dasm - OperatorIntrinsics:loop@5442-5(int,int):int
         -10 (-6.67% of base) : 12406.dasm - OperatorIntrinsics:loop@5442-8(long,int):long
         -15 (-6.55% of base) : 221436.dasm - System.Security.AccessControl.RawAcl:GetBinaryForm(System.Byte[],int):this
         -10 (-6.45% of base) : 12410.dasm - OperatorIntrinsics:loop@5442-10(long,int):long
         -10 (-6.37% of base) : 12404.dasm - OperatorIntrinsics:loop@5442-7(long,int):long
         -11 (-6.18% of base) : 197619.dasm - System.Formats.Cbor.CborReader:ReadEndMap():this

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

// tests

Found 149 files with textual diffs.

Summary of Code Size diffs:
(Lower is better)

Total bytes of base: 94593
Total bytes of diff: 92108
Total bytes of delta: -2485 (-2.63% of base)
    diff is an improvement.

Top file regressions (bytes):
           4 : 144403.dasm (0.95% of base)
           4 : 465526.dasm (0.72% of base)
           4 : 465563.dasm (0.94% of base)
           4 : 476005.dasm (1.27% of base)
           3 : 458476.dasm (2.94% of base)

Top file improvements (bytes):
        -377 : 448711.dasm (-2.77% of base)
         -36 : 443676.dasm (-5.29% of base)
         -36 : 443700.dasm (-5.29% of base)
         -32 : 74908.dasm (-4.40% of base)
         -29 : 393354.dasm (-9.15% of base)
         -28 : 447188.dasm (-11.24% of base)
         -28 : 447190.dasm (-8.21% of base)
         -28 : 447191.dasm (-8.21% of base)
         -27 : 443646.dasm (-8.79% of base)
         -26 : 135142.dasm (-5.35% of base)
         -25 : 467962.dasm (-7.67% of base)
         -21 : 140509.dasm (-48.84% of base)
         -21 : 447156.dasm (-0.38% of base)
         -20 : 237556.dasm (-5.59% of base)
         -20 : 447181.dasm (-6.19% of base)
         -20 : 447182.dasm (-6.19% of base)
         -20 : 447202.dasm (-9.01% of base)
         -19 : 101122.dasm (-5.59% of base)
         -19 : 382521.dasm (-2.14% of base)
         -19 : 82766.dasm (-5.59% of base)

149 total files with Code Size differences (144 improved, 5 regressed), 1 unchanged.

Top method regressions (bytes):
           4 ( 0.95% of base) : 144403.dasm - ExternalException:runtest():this
           4 ( 0.72% of base) : 465526.dasm - ExternalException:runtest():this
           4 ( 0.94% of base) : 465563.dasm - UserExceptionThread:runtest():this
           4 ( 1.27% of base) : 476005.dasm - UserException:Main(System.String[]):int
           3 ( 2.94% of base) : 458476.dasm - MarshalBoolArray:TestMethod_CallBackIn(int,System.Boolean[]):bool

Top method improvements (bytes):
        -377 (-2.77% of base) : 448711.dasm - Class1:foo(int)
         -36 (-5.29% of base) : 443676.dasm - PartialCompactionTest.PartialCompactionTest:RemoveObjects(System.Collections.Generic.List`1[[System.Object, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]])
         -36 (-5.29% of base) : 443700.dasm - PartialCompactionTest.PartialCompactionTest:RemoveObjects(System.Collections.Generic.List`1[[System.Object, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]])
         -32 (-4.40% of base) : 74908.dasm - Microsoft.CodeAnalysis.CommandLineParser:SplitCommandLineIntoArguments(System.String,bool,byref):System.Collections.Generic.IEnumerable`1[[System.String, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
         -29 (-9.15% of base) : 393354.dasm - System.Diagnostics.EventLogInternal:set_MaximumKilobytes(long):this
         -28 (-11.24% of base) : 447188.dasm - Mutual_recursion:seventhMethodFirstCallee@247(int,int,int,int,int,int,int,int,int,int,int):int
         -28 (-8.21% of base) : 447190.dasm - Mutual_recursion:seventhMethodSecondCalleeFastTailCall@302(int,int,int,int,int,int,int,int,int,int,int):int
         -28 (-8.21% of base) : 447191.dasm - Mutual_recursion:seventhMethodFirstCalleeFastTailCall@284(int,int,int,int,int,int,int,int,int,int,int):int
         -27 (-8.79% of base) : 443646.dasm - PartialCompactionTest.PartialCompactionTest:RemoveObjects(System.Collections.Generic.List`1[[PartialCompactionTest.PartialCompactionTest+ObjectWrapper, eco1, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]])
         -26 (-5.35% of base) : 135142.dasm - Class1:Main(System.String[]):int
         -25 (-7.67% of base) : 467962.dasm - ArrayOOM:RunTest():bool:this
         -21 (-48.84% of base) : 140509.dasm - GitHubIssue12479:callee(int,int,int,int,int,int,int,int):int
         -21 (-0.38% of base) : 447156.dasm - Program:Main():int
         -20 (-5.59% of base) : 237556.dasm - System.Xml.ValueHandle:TryReadBase64(System.Byte[],int,int,byref):bool:this
         -20 (-6.19% of base) : 447181.dasm - Mutual_recursion:fifthMethodSecondCallee@165(int,Point2D,Point2D,Point2D,Point2D,Point2D):int
         -20 (-6.19% of base) : 447182.dasm - Mutual_recursion:fifthMethodFirstCallee@147(int,Point2D,Point2D,Point2D,Point2D,Point2D):int
         -20 (-9.01% of base) : 447202.dasm - Mutual_recursion:eightMethodSecondCalleeFastTailCallReversed@469(int,int,int,int,int,int,int):int
         -19 (-5.59% of base) : 101122.dasm - Microsoft.Diagnostics.Tracing.EventPipeBlock:FromStream(FastSerialization.Deserializer):this
         -19 (-2.14% of base) : 382521.dasm - ILCompiler.PdbWriter.PdbWriter:WriteFileChecksums():this
         -19 (-5.59% of base) : 82766.dasm - Microsoft.Diagnostics.Tracing.EventPipeBlock:FromStream(FastSerialization.Deserializer):this

Top method regressions (percentages):
           3 ( 2.94% of base) : 458476.dasm - MarshalBoolArray:TestMethod_CallBackIn(int,System.Boolean[]):bool
           4 ( 1.27% of base) : 476005.dasm - UserException:Main(System.String[]):int
           4 ( 0.95% of base) : 144403.dasm - ExternalException:runtest():this
           4 ( 0.94% of base) : 465563.dasm - UserExceptionThread:runtest():this
           4 ( 0.72% of base) : 465526.dasm - ExternalException:runtest():this

Top method improvements (percentages):
         -21 (-48.84% of base) : 140509.dasm - GitHubIssue12479:callee(int,int,int,int,int,int,int,int):int
         -13 (-38.24% of base) : 474397.dasm - FastTailCallCandidates:CallerEnregisterableAmd64WindowsStructs8Bytes(int,int):int
         -17 (-29.31% of base) : 474362.dasm - FastTailCallCandidates:CalleeAmd64WindowsStructs4Bytes(StructSizeFourNotExplicit):int
         -17 (-28.81% of base) : 474364.dasm - FastTailCallCandidates:CalleeAmd64WindowsStructs3Bytes(StructSizeThreeNotExplicit):int
         -17 (-26.98% of base) : 474396.dasm - FastTailCallCandidates:CalleeEnregisterableAmd64WindowsStructs8Bytes(StructSizeEightNotExplicit):int
         -17 (-26.15% of base) : 474358.dasm - FastTailCallCandidates:CalleeAmd64WindowsStructs6Bytes(StructSizeSixNotExplicit):int
         -17 (-26.15% of base) : 474360.dasm - FastTailCallCandidates:CalleeAmd64WindowsStructs5Bytes(StructSizeFiveNotExplicit):int
         -17 (-26.15% of base) : 474398.dasm - FastTailCallCandidates:CalleeAmd64WindowsStructs7Bytes(StructSizeSevenNotExplicit):int
         -18 (-21.69% of base) : 474387.dasm - FastTailCallCandidates:DoubleCountRetBuffCallee(StructSizeEightIntNotExplicit,StructSizeEightIntNotExplicit,StructSizeEightIntNotExplicit,StructSizeEightIntNotExplicit,StructSizeEightIntNotExplicit):StructSizeThirtyTwo
         -17 (-20.24% of base) : 443929.dasm - Test:InitBoolArray(int):System.Boolean[]
         -17 (-20.24% of base) : 444527.dasm - Test:InitBoolArray(int):System.Boolean[]
         -17 (-20.24% of base) : 444537.dasm - Test:InitBoolArray(int):System.Boolean[]
         -17 (-20.24% of base) : 444609.dasm - ArrayMarshal:GetExpectedOutBoolArray(int):System.Boolean[]
         -17 (-20.24% of base) : 444635.dasm - ArrayMarshal:GetExpectedOutBoolArray(int):System.Boolean[]
         -12 (-19.05% of base) : 140636.dasm - CTest:CheckDoubleAlignment(long)
         -13 (-15.85% of base) : 474361.dasm - FastTailCallCandidates:CallerAmd64WindowsStructs5Bytes(int,int):int
         -14 (-15.56% of base) : 234513.dasm - System.Data.SqlTypes.SqlDateTime:IsLeapYear(int):bool
         -10 (-15.15% of base) : 421773.dasm - System.Text.RegularExpressions.RegexCharClass:CanEasilyEnumerateSetContents(System.String):bool
         -16 (-14.29% of base) : 442136.dasm - System.Security.Cryptography.SymmetricAlgorithm:set_FeedbackSize(int):this
         -13 (-14.13% of base) : 474365.dasm - FastTailCallCandidates:CallerAmd64WindowsStructs3Bytes(ubyte,ubyte):int

149 total methods with Code Size differences (144 improved, 5 regressed), 1 unchanged.

@BruceForstall BruceForstall marked this pull request as ready for review December 4, 2020 19:00
@BruceForstall
Copy link
Contributor Author

@am11 That would be a different issue. I don't think we can eliminate the zero extend in this case because we need to whole register to be set on return, not just the low byte. clang might assume that for bool returning functions only the low byte is valid.

@BruceForstall
Copy link
Contributor Author

@AndyAyersMS What do you think about this change? Smallish benefit, appears not to hit on arm (maybe due to phase ordering?). Is it the "right place" for such a "peep"?

@AndyAyersMS
Copy link
Member

Seems like the right place. Can you show an example diff?

@BruceForstall
Copy link
Contributor Author

For:

static int Mod2(int iterations)
{
    int count = 0;
    for (var i = 0; i < iterations; i++)
    {
        if (i % 2 == 0) { count++; }
    }
    return count;
}

the win-x64 diff is:

<        448BC2               mov      r8d, edx
<        41C1E81F             shr      r8d, 31
<        4403C2               add      r8d, edx
<        4183E0FE             and      r8d, -2
<        448BCA               mov      r9d, edx
<        452BC8               sub      r9d, r8d
---
>        F6C201               test     dl, 1

@EgorBo
Copy link
Member

EgorBo commented Dec 4, 2020

It's placed inside GT_JTRUE node which means it won't work for e.g. return x % 2 == 0 Shouldn't it be inside case GT_EQ/GT_NE ?

@BruceForstall
Copy link
Contributor Author

@EgorBo I don't think so, because in the return case we need to manifest the result value in a register.

@EgorBo
Copy link
Member

EgorBo commented Dec 5, 2020

@ViktorHofer
Copy link
Member

// Auto-generated message

69e114c which was merged 12/7 removed the intermediate src/coreclr/src/ folder. This PR needs to be updated as it touches files in that directory which causes conflicts.

To update your commits you can use this bash script: https://gist.github.com/ViktorHofer/6d24f62abdcddb518b4966ead5ef3783. Feel free to use the comment section of the gist to improve the script for others.

@AndyAyersMS
Copy link
Member

@BruceForstall you have merge conflicts to resolve here.

@AndyAyersMS
Copy link
Member

Also agree with @EgorBo -- can you look into the case where this is not under JTRUE?

@JulieLeeMSFT JulieLeeMSFT added this to the 6.0.0 milestone Feb 8, 2021
Base automatically changed from master to main March 1, 2021 09:07
@BruceForstall
Copy link
Contributor Author

ping myself

@BruceForstall
Copy link
Contributor Author

ping myself again

@BruceForstall
Copy link
Contributor Author

ping myself

@BruceForstall
Copy link
Contributor Author

Ok, I moved the change to post-order EQ/NE processing (instead of JTRUE processing), and the diffs are almost strictly better (there are a couple cases where we inject a reg/reg move for no good reason...)

Example diffs (spmi windows x64 benchmarks):


Summary of Code Size diffs:
(Lower is better)

Total bytes of base: 28855
Total bytes of diff: 28456
Total bytes of delta: -399 (-1.38% of base)
    diff is an improvement.
Detail diffs


Top file improvements (bytes):
         -26 : 14289.dasm (-0.43% of base)
         -26 : 16701.dasm (-0.43% of base)
         -23 : 9187.dasm (-1.67% of base)
         -17 : 27372.dasm (-0.90% of base)
         -16 : 15506.dasm (-1.51% of base)
         -16 : 29.dasm (-7.21% of base)
         -16 : 11984.dasm (-2.10% of base)
         -16 : 19344.dasm (-0.40% of base)
         -14 : 21936.dasm (-1.99% of base)
         -14 : 1859.dasm (-6.73% of base)
         -13 : 27370.dasm (-2.31% of base)
         -13 : 4128.dasm (-9.63% of base)
         -13 : 13381.dasm (-1.95% of base)
         -13 : 4554.dasm (-1.80% of base)
         -13 : 27502.dasm (-3.15% of base)
         -13 : 7942.dasm (-4.29% of base)
         -12 : 19751.dasm (-7.32% of base)
         -12 : 1470.dasm (-3.54% of base)
         -11 : 11212.dasm (-3.01% of base)
         -11 : 14971.dasm (-11.96% of base)

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

Top method improvements (bytes):
         -26 (-0.43% of base) : 14289.dasm - Jil.Deserialize.Methods:ParseISO8601DateThunkReader(byref,System.Char[],int,int):System.DateTime
         -26 (-0.43% of base) : 16701.dasm - Jil.Deserialize.Methods:ParseISO8601Date(System.IO.TextReader,System.Char[],int,int):System.DateTime
         -23 (-1.67% of base) : 9187.dasm - System.Threading.Barrier:SignalAndWait(int,System.Threading.CancellationToken):bool:this
         -17 (-0.90% of base) : 27372.dasm - System.Text.Base64Encoding:GetBytes(System.Byte[],int,int,System.Byte[],int):int:this
         -16 (-1.51% of base) : 15506.dasm - ProtoBuf.Compiler.CompilerContext:Switch(ProtoBuf.Compiler.CodeLabel[]):this
         -16 (-7.21% of base) : 29.dasm - System.String:GetNonRandomizedHashCode():int:this
         -16 (-2.10% of base) : 11984.dasm - System.Collections.Generic.SortedSet`1[__Canon][System.__Canon]:ConstructRootFromSortedArray(System.__Canon[],int,int,Node[__Canon]):Node[__Canon]
         -16 (-0.40% of base) : 19344.dasm - System.Reflection.Metadata.Ecma335.MetadataBuilder:.ctor(int,int,int,int):this
         -14 (-1.99% of base) : 21936.dasm - System.Convert:TryDecodeFromUtf16(System.ReadOnlySpan`1[Char],System.Span`1[Byte],byref,byref):bool
         -14 (-6.73% of base) : 1859.dasm - System.Globalization.GregorianCalendar:IsValidDay(int,int,int,int):bool:this
         -13 (-2.31% of base) : 27370.dasm - System.Xml.ValueHandle:ToByteArray():System.Byte[]:this
         -13 (-9.63% of base) : 4128.dasm - Microsoft.Extensions.Logging.LogValuesFormatter:FindBraceIndex(System.String,ushort,int,int):int
         -13 (-1.95% of base) : 13381.dasm - System.Net.Security.SslSessionsCache:<CacheCredential>g__ShrinkCredentialCache|5_0()
         -13 (-1.80% of base) : 4554.dasm - System.Collections.Generic.SortedSet`1[Int32][System.Int32]:ConstructRootFromSortedArray(System.Int32[],int,int,Node[Int32]):Node[Int32]
         -13 (-3.15% of base) : 27502.dasm - System.Globalization.GregorianCalendar:GetAbsoluteDate(int,int,int):long
         -13 (-4.29% of base) : 7942.dasm - System.Linq.Tests.Perf_Enumerable:AppendPrepend(System.Linq.Tests.LinqTestData):this
         -12 (-7.32% of base) : 19751.dasm - System.Reflection.Metadata.Ecma335.MethodBodyStreamEncoder:.ctor(System.Reflection.Metadata.BlobBuilder):this
         -12 (-3.54% of base) : 1470.dasm - System.SpanHelpers:ClearWithReferences(byref,long)
         -11 (-3.01% of base) : 11212.dasm - System.String:GetNonRandomizedHashCodeOrdinalIgnoreCase():int:this
         -11 (-11.96% of base) : 14971.dasm - System.Formats.Cbor.CborReader:AdvanceDataItemCounters():this

Top method improvements (percentages):
          -9 (-34.62% of base) : 10637.dasm - <>c:<Setup>b__6_0(int):ubyte:this
          -9 (-34.62% of base) : 22547.dasm - <>c:<Setup>b__7_0(int):int:this
         -10 (-15.15% of base) : 2182.dasm - System.Text.RegularExpressions.RegexCharClass:CanEasilyEnumerateSetContents(System.String):bool
         -11 (-13.25% of base) : 24057.dasm - System.Formats.Cbor.CborWriter:AdvanceDataItemCounters():this
         -11 (-11.96% of base) : 14971.dasm - System.Formats.Cbor.CborReader:AdvanceDataItemCounters():this
         -13 (-9.63% of base) : 4128.dasm - Microsoft.Extensions.Logging.LogValuesFormatter:FindBraceIndex(System.String,ushort,int,int):int
         -12 (-7.32% of base) : 19751.dasm - System.Reflection.Metadata.Ecma335.MethodBodyStreamEncoder:.ctor(System.Reflection.Metadata.BlobBuilder):this
         -16 (-7.21% of base) : 29.dasm - System.String:GetNonRandomizedHashCode():int:this
         -14 (-6.73% of base) : 1859.dasm - System.Globalization.GregorianCalendar:IsValidDay(int,int,int,int):bool:this
         -11 (-6.36% of base) : 14985.dasm - System.Formats.Cbor.CborReader:ReadEndMap():this
         -13 (-4.29% of base) : 7942.dasm - System.Linq.Tests.Perf_Enumerable:AppendPrepend(System.Linq.Tests.LinqTestData):this
         -11 (-3.78% of base) : 4176.dasm - SciMark2.Random:initialize(int):this
         -10 (-3.60% of base) : 3981.dasm - System.Threading.LowLevelSpinWaiter:Wait(int,int,int)
         -12 (-3.54% of base) : 1470.dasm - System.SpanHelpers:ClearWithReferences(byref,long)
         -13 (-3.15% of base) : 27502.dasm - System.Globalization.GregorianCalendar:GetAbsoluteDate(int,int,int):long
         -11 (-3.01% of base) : 11212.dasm - System.String:GetNonRandomizedHashCodeOrdinalIgnoreCase():int:this
         -13 (-2.31% of base) : 27370.dasm - System.Xml.ValueHandle:ToByteArray():System.Byte[]:this
         -16 (-2.10% of base) : 11984.dasm - System.Collections.Generic.SortedSet`1[__Canon][System.__Canon]:ConstructRootFromSortedArray(System.__Canon[],int,int,Node[__Canon]):Node[__Canon]
          -9 (-2.05% of base) : 4254.dasm - System.Threading.SpinWait:SpinOnceCore(int):this
         -14 (-1.99% of base) : 21936.dasm - System.Convert:TryDecodeFromUtf16(System.ReadOnlySpan`1[Char],System.Span`1[Byte],byref,byref):bool

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


@BruceForstall
Copy link
Contributor Author

@AndyAyersMS @EgorBo Take another look?

Convert `x % 2^c == 0` to `x & (2^c-1) == 0` to generate better code.
@BruceForstall
Copy link
Contributor Author

CI failure is #52031

@BruceForstall BruceForstall merged commit eb7ef11 into dotnet:main Apr 29, 2021
@BruceForstall BruceForstall deleted the Fix5844 branch April 29, 2021 20:35
@ghost ghost locked as resolved and limited conversation to collaborators May 29, 2021
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

Archived in project

Development

Successfully merging this pull request may close these issues.

7 participants