Uh oh!
There was an error while loading. Please reload this page.
[JIT] ARM64 - Temporary fix for ldp/stp optimizations - #90534
Conversation
ghost
commented
Aug 14, 2023
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsResolves #85765 With the latest, the code-gen is quite different from what was reported in the issue. Current code-gen: ; Assembly listing for method Program:Main() (FullOpts); Emitting BLENDED_CODE for generic ARM64 - Windows; FullOpts code; optimized code; fp based frame; partially interruptible; No PGO data; 0 inlinees with PGO data; 2 single block inlinees; 0 inlinees without PGO data; invoked as altjit; Final local variable assignments;;* V00 loc0 [V00 ] ( 0, 0 ) struct ( 8) zero-ref ld-addr-op <S1>;# V01 OutArgs [V01 ] ( 1, 1 ) struct ( 0) [sp+0x00] do-not-enreg[XS] addr-exposed "OutgoingArgSpace";* V02 tmp1 [V02 ] ( 0, 0 ) struct ( 8) zero-ref ld-addr-op "Inline ldloca(s) first use temp" <S1>;* V03 tmp2 [V03 ] ( 0, 0 ) struct ( 8) zero-ref ld-addr-op "Inline ldloca(s) first use temp" <S0>;* V04 tmp3 [V04 ] ( 0, 0 ) ubyte -> zero-ref "field V00.F0 (fldOffset=0x0)" P-INDEP;* V05 tmp4 [V05 ] ( 0, 0 ) bool -> zero-ref single-def "field V00.F1 (fldOffset=0x1)" P-INDEP;* V06 tmp5 [V06 ] ( 0, 0 ) bool -> zero-ref "field V00.F2 (fldOffset=0x2)" P-INDEP;* V07 tmp6 [V07 ] ( 0, 0 ) ubyte -> zero-ref single-def "field V02.F0 (fldOffset=0x0)" P-INDEP;* V08 tmp7 [V08 ] ( 0, 0 ) bool -> zero-ref single-def "field V02.F1 (fldOffset=0x1)" P-INDEP;* V09 tmp8 [V09 ] ( 0, 0 ) bool -> zero-ref single-def "field V02.F2 (fldOffset=0x2)" P-INDEP;; Lcl frame size = 0G_M27646_IG01: stp fp, lr,[sp, #-0x10]!mov fp,sp ;; size=8 bbWeight=1 PerfScore 1.50G_M27646_IG02:mov w0, wzr movz x1, #0xD1FFAB1E // code for System.Console:WriteLine(bool) movk x1, #0xD1FFAB1ELSL #16 movk x1, #0xD1FFAB1ELSL #32 ldr x1,[x1] blr x1 ;; size=24 bbWeight=1 PerfScore 6.00G_M27646_IG03: ldp fp, lr,[sp], #0x10ret lr ;; size=8 bbWeight=1 PerfScore 2.00; Total bytes of code 40, prolog size 8, PerfScore 13.50, instruction count 10, allocated bytes for code 40 (MethodHash=cb019401) for method Program:Main() (FullOpts)
|
TIHan
commented
Aug 14, 2023
@jakobbotsch What did you do to determine which PR could repo this? Did you just do a bisect? |
jakobbotsch
commented
Aug 14, 2023
Yes. I keep Core_Roots compiled for all JIT commits so that I can quickly do that. |
TIHan
commented
Aug 14, 2023
That's a lot of Core_Roots :) |
TIHan
commented
Aug 14, 2023
I checked out e62cb64 and did a fresh/clean checked build and the codegen is the same. Maybe I should try to go back further. |
jakobbotsch
commented
Aug 14, 2023
What if you mark |
TIHan
commented
Aug 14, 2023
Marking it as NoInline I was able to reproduce it, but only on that commit. Latest code-gen is: ; Assembly listing for method Program:Main() (FullOpts); Emitting BLENDED_CODE for generic ARM64 - Windows; FullOpts code; optimized code; fp based frame; partially interruptible; No PGO data; invoked as altjit; Final local variable assignments;; V00 loc0 [V00 ] ( 5, 5 ) struct ( 8) [fp+0x18] do-not-enreg[SB] ld-addr-op <S1>;# V01 OutArgs [V01 ] ( 1, 1 ) struct ( 0) [sp+0x00] do-not-enreg[XS] addr-exposed "OutgoingArgSpace"; V02 tmp1 [V02,T03] ( 1, 1 ) ubyte -> [fp+0x18] do-not-enreg[] "field V00.F0 (fldOffset=0x0)" P-DEP; V03 tmp2 [V03,T02] ( 2, 2 ) bool -> [fp+0x19] do-not-enreg[] "field V00.F1 (fldOffset=0x1)" P-DEP; V04 tmp3 [V04,T00] ( 4, 4 ) bool -> [fp+0x1A] do-not-enreg[] single-def "field V00.F2 (fldOffset=0x2)" P-DEP; V05 rat0 [V05,T01] ( 2, 4 ) struct ( 8) [fp+0x10] do-not-enreg[SF] "Return value temp for an odd struct return size" <S1>;; Lcl frame size = 16G_M27646_IG01: ;; offset=0x0000 stp fp, lr,[sp, #-0x20]!mov fp,sp ;; size=8 bbWeight=1 PerfScore 1.50G_M27646_IG02: ;; offset=0x0008 movz x0, #0xC408 // code for Program:M4():S1 movk x0, #0x5CDCLSL #16 movk x0, #0x7FFDLSL #32 ldr x0,[x0] blr x0str w0,[fp, #0x10] // [V05 rat0] ldrh w0,[fp, #0x10] strh w0,[fp, #0x18] ldrb w0,[fp, #0x12] strb w0,[fp, #0x1A] ldrb w0,[fp, #0x1A] // [V04 tmp3] ldrb w1,[fp, #0x19] // [V03 tmp2] orr w0, w0, w1 strb w0,[fp, #0x1A] // [V04 tmp3] ldrb w0,[fp, #0x1A] // [V04 tmp3] movz x1, #0x4CD8 // code for System.Console:WriteLine(bool) movk x1, #0x5CFFLSL #16 movk x1, #0x7FFDLSL #32 ldr x1,[x1] blr x1 ;; size=80 bbWeight=1 PerfScore 25.50G_M27646_IG03: ;; offset=0x0058 ldp fp, lr,[sp], #0x20ret lr ;; size=8 bbWeight=1 PerfScore 2.00; Total bytes of code 96, prolog size 8, PerfScore 38.60, instruction count 24, allocated bytes for code 96 (MethodHash=cb019401) for method Program:Main() (FullOpts); ============================================================ |
jakobbotsch
commented
Aug 14, 2023
This is in the backend, so we should fix it even if it no longer repros with this specific example. #86491 is a change in morph so it did not fix the backend bug. |
TIHan
commented
Aug 14, 2023
Looks like it is, but all I can do is try to fix it based on this commit and hope that it is correct considering there are no other examples that reproduce it in the latest. |
jakobbotsch
commented
Aug 14, 2023
Fixing the backend bug on a commit that is a few months older is just fine. You should be able to test your fix on that commit. I did the same in #90246. |
TIHan
commented
Aug 14, 2023
It doesn't leave me feeling confident knowing that this cannot be reproduced in latest. |
jakobbotsch
commented
Aug 14, 2023
How would you know that the problem cannot be reproduced in |
jakobbotsch
commented
Aug 14, 2023
Here is an example that reproduces the problem on main: usingSystem;usingSystem.Runtime.CompilerServices;publicunsafeclassProgram{publicstaticvoidMain(){byte*bytes=stackallocbyte[1024];bytes[0x1A]=1;bytes[0x1B]=2;intsum=Foo(bytes);Console.WriteLine(sum);}[MethodImpl(MethodImplOptions.NoInlining)]publicstaticintFoo(byte*b){returnUnsafe.ReadUnaligned<int>(refb[0x1A])+Unsafe.ReadUnaligned<int>(refb[0x1B]);}}Expected: 515 |
TIHan
commented
Aug 14, 2023
That's the tricky part for this problem. I have no idea what I'm looking at as it's new to me. |
TIHan
commented
Aug 15, 2023
That new example, interestingly, it outputs 515 in e62cb64 . |
jakobbotsch
commented
Aug 15, 2023
…h the optimized ldr/str pair
@jakobbotsch I made a quick fix, but I put in a "TODO". The problem is a little complicated, but the issue is that 'imm' and/or 'prevImm' are assumed to be "scaled" when attempting to do a |
TIHan
commented
Aug 15, 2023
@dotnet/jit-contrib @BruceForstall@jakobbotsch this is ready, pending CI. |
ldp/stp optimizationsUh oh!
There was an error while loading. Please reload this page.
BruceForstall
commented
Aug 16, 2023
BruceForstall
left a comment
There was a problem hiding this comment.
LGTM
We should back-port this to .NET 8.
In the future, I'd like to see the "peephole optimization" code deal in "actual" values, not "encoded" values.
TIHan
commented
Aug 16, 2023
/backport to release/8.0 |
Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5881464622 |
@TIHan an error occurred while backporting to release/8.0, please check the run log for details! Error: @TIHan is not a repo collaborator, backporting is not allowed. If you're a collaborator please make sure your dotnet team membership visibility is set to Public on https://github.com/orgs/dotnet/people?query=TIHan |
TIHan
commented
Aug 16, 2023
/backport to release/8.0 |
Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5882707392 |
jakobbotsch
commented
Aug 16, 2023
@TIHan The test added here doesn't build -- seems like CI was red when this PR was merged. |
elinor-fung
commented
Aug 16, 2023
@TIHan the test added doesn't build: |
TIHan
commented
Aug 16, 2023
Ok, will make a quick PR to fix this. |
TIHan
commented
Aug 16, 2023
jkotas
commented
Aug 16, 2023
I am going to revert this. This can be introducing number of other problems since the CI was all read when this was merged. |
This is the same PR as this but with the test fix. My fault for not checking. |
Resolves#85765
With the latest, the code-gen is quite different from what was reported in the issue, and therefore doesn't reproduce. But the issue still exists and is able to be reproduced by a different sample: