Open MineCake147E opened 2 years ago
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch See info in area-owners.md if you want to be subscribed.
Author: | MineCake147E |
---|---|
Assignees: | - |
Labels: | `tenet-performance`, `area-CodeGen-coreclr` |
Milestone: | - |
cc @dotnet/jit-contrib.
Related work: https://github.com/dotnet/runtime/pull/81267
Confirmed on latest nightly with Compiler Explorer:
// crossgen2 8.0.0-preview.3.23168.99+281c462b029c5056cdd446da86692e08a9377b01
C:AddCarry(uint,uint,byref):uint:
lea eax, [rcx+rdx]
cmp eax, ecx
setb dl
mov byte ptr [r8], dl
ret
C:SubtractIfLargerOrEqual(uint,uint,byref):uint:
mov eax, ecx
sub eax, edx
xor edx, edx
cmp eax, ecx
seta dl
test edx, edx
cmovne eax, ecx
mov byte ptr [r8], dl
ret
Also related: https://github.com/dotnet/runtime/pull/82750
For AddCarry
, I was able to recognize the pattern, but it appears this isn't common and doesn't even appear in our SuperPMI diff tool.
AddCarry (and SubtractBorrow) is one that we’d like to explicitly take advantage of in BigInteger, Int128, and UInt128.
For the latter two it’s just a simple scenario like the original post gives. For BigInteger it needs to be many carry’s that are done in a loop and is quite a bit more complex
For these types we’re currently using an slightly different bit of code that accounts for the lack of support for AddCarry being recognized today
Description
RyuJIT doesn't seem to be interested in flags set by instructions other than
cmp
andtest
.add
instruction and flagsFor unsigned integers, if the result of the addition overflows and CF is set, the result of the addition is less than one of the input operands.
In this code,
Results in
In this case, LLVM utilizes this fact, for example:
sub
instruction with redundantcmp
instructionIt might be common to subtract a value from a register only when the value of the register is greater than or equal to that value.
The
cmp
instruction does the same comparison as thesub
instruction, so thesub
andcmp
instructions with the same register operands change flags in the same way.In this specific case, LLVM mysteriously transforms this calculation into something like
res = left - (left < right ? 0 : right)
.Configuration
SharpLab
Compiler Explorer
Regression?
No
Data
Analysis
category:cq theme:basic-cq