Skip to content

[JIT] ARM64 - Temporary fix for ldp/stp optimizations - #90534

Merged
TIHan merged 5 commits into
dotnet:mainfrom
TIHan:runtime_85765
Aug 16, 2023
Merged

[JIT] ARM64 - Temporary fix for ldp/stp optimizations#90534
TIHan merged 5 commits into
dotnet:mainfrom
TIHan:runtime_85765

Conversation

@TIHan

@TIHanTIHan commented Aug 14, 2023

Copy link
Copy Markdown
Contributor

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:

usingSystem;usingSystem.Runtime.CompilerServices;// Expected: 515// Actual: 0publicunsafeclassProgram{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]);}}

@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Aug 14, 2023
@ghostghost assigned TIHanAug 14, 2023
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

Resolves #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)
Author:TIHan
Assignees:-
Labels:

area-CodeGen-coreclr

Milestone:-

@jakobbotsch

jakobbotsch commented Aug 14, 2023

Copy link
Copy Markdown
Member

This repros up until #86491 was merged. Can you check out e62cb64 (the parent of #86491) and repro the problem there? With altjit and TC=0 I get the same codegen as in the issue on that commit.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

@jakobbotsch What did you do to determine which PR could repo this? Did you just do a bisect?

@jakobbotsch

Copy link
Copy Markdown
Member

@jakobbotsch What did you do to determine which PR could repo this? Did you just do a bisect?

Yes. I keep Core_Roots compiled for all JIT commits so that I can quickly do that.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Yes. I keep Core_Roots compiled for all JIT commits so that I can quickly do that.

That's a lot of Core_Roots :)

@TIHan

Copy link
Copy Markdown
ContributorAuthor

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

Copy link
Copy Markdown
Member

What if you mark M4 as NoInlining? It is not being inlined for me, but it seems it is inlined in your codegen.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

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

Copy link
Copy Markdown
Member

Marking it as NoInline I was able to reproduce it, but only on that commit.

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

Copy link
Copy Markdown
ContributorAuthor

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.

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

Copy link
Copy Markdown
Member

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.

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

Copy link
Copy Markdown
ContributorAuthor

It doesn't leave me feeling confident knowing that this cannot be reproduced in latest.

@jakobbotsch

Copy link
Copy Markdown
Member

How would you know that the problem cannot be reproduced in main? Once you understand the problem you might even be able to construct an example yourself.

@jakobbotsch

Copy link
Copy Markdown
Member

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
Actual: 0

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Once you understand the problem you might even be able to construct an example yourself.

That's the tricky part for this problem. I have no idea what I'm looking at as it's new to me.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

That new example, interestingly, it outputs 515 in e62cb64 .

@jakobbotsch

Copy link
Copy Markdown
Member

That new example, interestingly, it outputs 515 in e62cb64 .

Odd, I get the same codegen on main and e62cb64: a ldp w1, w0, [x0, #0x68] that incorrectly loads at 0x1A * 4.

@TIHan

TIHan commented Aug 15, 2023

Copy link
Copy Markdown
ContributorAuthor

@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 ldr/str pair optimization to ldp/stp respectively. The bug is that 'imm' and/or 'prevImm' are not "scaled" so it's using the wrong values for the comparisons. We should fix this, but we can fix it later.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

@dotnet/jit-contrib @BruceForstall@jakobbotsch this is ready, pending CI.

@TIHanTIHan changed the title Added regression test 85765[JIT] ARM64 - Temporary fix for ldp/stp optimizationsAug 15, 2023
Comment threadsrc/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs Outdated
@BruceForstall

Copy link
Copy Markdown
Contributor

No diffs

@BruceForstallBruceForstall left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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
TIHan merged commit 99a60c6 into dotnet:mainAug 16, 2023
@TIHan

Copy link
Copy Markdown
ContributorAuthor

/backport to release/8.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5881464622

@github-actions

Copy link
Copy Markdown
Contributor

@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

Copy link
Copy Markdown
ContributorAuthor

/backport to release/8.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5882707392

@jakobbotsch

Copy link
Copy Markdown
Member

@TIHan The test added here doesn't build -- seems like CI was red when this PR was merged.

@elinor-fung

Copy link
Copy Markdown
Member

@TIHan the test added doesn't build: src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs(59,27): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context [/__w/1/s/src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.csproj]

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Ok, will make a quick PR to fix this.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

#90698

@jkotas

Copy link
Copy Markdown
Member

I am going to revert this. This can be introducing number of other problems since the CI was all read when this was merged.

jkotas added a commit that referenced this pull request Aug 16, 2023
@TIHan

TIHan commented Aug 16, 2023

Copy link
Copy Markdown
ContributorAuthor

This is the same PR as this but with the test fix.

My fault for not checking.

@ghostghost locked as resolved and limited conversation to collaborators Sep 16, 2023
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR 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.

JIT: Invalid ldp optimization with locals

6 participants

@TIHan@jakobbotsch@BruceForstall@elinor-fung@jkotas@markples
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
[JIT] ARM64 - Temporary fix for `ldp`/`stp` optimizations by TIHan · Pull Request #90534 · dotnet/runtime · GitHub
Skip to content

[JIT] ARM64 - Temporary fix for ldp/stp optimizations - #90534

Merged
TIHan merged 5 commits into
dotnet:mainfrom
TIHan:runtime_85765
Aug 16, 2023
Merged

[JIT] ARM64 - Temporary fix for ldp/stp optimizations#90534
TIHan merged 5 commits into
dotnet:mainfrom
TIHan:runtime_85765

Conversation

@TIHan

@TIHanTIHan commented Aug 14, 2023

Copy link
Copy Markdown
Contributor

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:

usingSystem;usingSystem.Runtime.CompilerServices;// Expected: 515// Actual: 0publicunsafeclassProgram{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]);}}

@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Aug 14, 2023
@ghostghost assigned TIHanAug 14, 2023
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

Resolves #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)
Author:TIHan
Assignees:-
Labels:

area-CodeGen-coreclr

Milestone:-

@jakobbotsch

jakobbotsch commented Aug 14, 2023

Copy link
Copy Markdown
Member

This repros up until #86491 was merged. Can you check out e62cb64 (the parent of #86491) and repro the problem there? With altjit and TC=0 I get the same codegen as in the issue on that commit.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

@jakobbotsch What did you do to determine which PR could repo this? Did you just do a bisect?

@jakobbotsch

Copy link
Copy Markdown
Member

@jakobbotsch What did you do to determine which PR could repo this? Did you just do a bisect?

Yes. I keep Core_Roots compiled for all JIT commits so that I can quickly do that.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Yes. I keep Core_Roots compiled for all JIT commits so that I can quickly do that.

That's a lot of Core_Roots :)

@TIHan

Copy link
Copy Markdown
ContributorAuthor

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

Copy link
Copy Markdown
Member

What if you mark M4 as NoInlining? It is not being inlined for me, but it seems it is inlined in your codegen.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

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

Copy link
Copy Markdown
Member

Marking it as NoInline I was able to reproduce it, but only on that commit.

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

Copy link
Copy Markdown
ContributorAuthor

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.

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

Copy link
Copy Markdown
Member

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.

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

Copy link
Copy Markdown
ContributorAuthor

It doesn't leave me feeling confident knowing that this cannot be reproduced in latest.

@jakobbotsch

Copy link
Copy Markdown
Member

How would you know that the problem cannot be reproduced in main? Once you understand the problem you might even be able to construct an example yourself.

@jakobbotsch

Copy link
Copy Markdown
Member

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
Actual: 0

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Once you understand the problem you might even be able to construct an example yourself.

That's the tricky part for this problem. I have no idea what I'm looking at as it's new to me.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

That new example, interestingly, it outputs 515 in e62cb64 .

@jakobbotsch

Copy link
Copy Markdown
Member

That new example, interestingly, it outputs 515 in e62cb64 .

Odd, I get the same codegen on main and e62cb64: a ldp w1, w0, [x0, #0x68] that incorrectly loads at 0x1A * 4.

@TIHan

TIHan commented Aug 15, 2023

Copy link
Copy Markdown
ContributorAuthor

@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 ldr/str pair optimization to ldp/stp respectively. The bug is that 'imm' and/or 'prevImm' are not "scaled" so it's using the wrong values for the comparisons. We should fix this, but we can fix it later.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

@dotnet/jit-contrib @BruceForstall@jakobbotsch this is ready, pending CI.

@TIHanTIHan changed the title Added regression test 85765[JIT] ARM64 - Temporary fix for ldp/stp optimizationsAug 15, 2023
Comment threadsrc/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs Outdated
@BruceForstall

Copy link
Copy Markdown
Contributor

No diffs

@BruceForstallBruceForstall left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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
TIHan merged commit 99a60c6 into dotnet:mainAug 16, 2023
@TIHan

Copy link
Copy Markdown
ContributorAuthor

/backport to release/8.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5881464622

@github-actions

Copy link
Copy Markdown
Contributor

@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

Copy link
Copy Markdown
ContributorAuthor

/backport to release/8.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5882707392

@jakobbotsch

Copy link
Copy Markdown
Member

@TIHan The test added here doesn't build -- seems like CI was red when this PR was merged.

@elinor-fung

Copy link
Copy Markdown
Member

@TIHan the test added doesn't build: src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs(59,27): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context [/__w/1/s/src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.csproj]

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Ok, will make a quick PR to fix this.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

#90698

@jkotas

Copy link
Copy Markdown
Member

I am going to revert this. This can be introducing number of other problems since the CI was all read when this was merged.

jkotas added a commit that referenced this pull request Aug 16, 2023
@TIHan

TIHan commented Aug 16, 2023

Copy link
Copy Markdown
ContributorAuthor

This is the same PR as this but with the test fix.

My fault for not checking.

@ghostghost locked as resolved and limited conversation to collaborators Sep 16, 2023
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR 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.

JIT: Invalid ldp optimization with locals

6 participants

@TIHan@jakobbotsch@BruceForstall@elinor-fung@jkotas@markples
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [JIT] ARM64 - Temporary fix for `ldp`/`stp` optimizations by TIHan · Pull Request #90534 · dotnet/runtime · GitHub
Skip to content

[JIT] ARM64 - Temporary fix for ldp/stp optimizations - #90534

Merged
TIHan merged 5 commits into
dotnet:mainfrom
TIHan:runtime_85765
Aug 16, 2023
Merged

[JIT] ARM64 - Temporary fix for ldp/stp optimizations#90534
TIHan merged 5 commits into
dotnet:mainfrom
TIHan:runtime_85765

Conversation

@TIHan

@TIHanTIHan commented Aug 14, 2023

Copy link
Copy Markdown
Contributor

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:

usingSystem;usingSystem.Runtime.CompilerServices;// Expected: 515// Actual: 0publicunsafeclassProgram{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]);}}

@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Aug 14, 2023
@ghostghost assigned TIHanAug 14, 2023
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

Resolves #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)
Author:TIHan
Assignees:-
Labels:

area-CodeGen-coreclr

Milestone:-

@jakobbotsch

jakobbotsch commented Aug 14, 2023

Copy link
Copy Markdown
Member

This repros up until #86491 was merged. Can you check out e62cb64 (the parent of #86491) and repro the problem there? With altjit and TC=0 I get the same codegen as in the issue on that commit.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

@jakobbotsch What did you do to determine which PR could repo this? Did you just do a bisect?

@jakobbotsch

Copy link
Copy Markdown
Member

@jakobbotsch What did you do to determine which PR could repo this? Did you just do a bisect?

Yes. I keep Core_Roots compiled for all JIT commits so that I can quickly do that.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Yes. I keep Core_Roots compiled for all JIT commits so that I can quickly do that.

That's a lot of Core_Roots :)

@TIHan

Copy link
Copy Markdown
ContributorAuthor

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

Copy link
Copy Markdown
Member

What if you mark M4 as NoInlining? It is not being inlined for me, but it seems it is inlined in your codegen.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

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

Copy link
Copy Markdown
Member

Marking it as NoInline I was able to reproduce it, but only on that commit.

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

Copy link
Copy Markdown
ContributorAuthor

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.

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

Copy link
Copy Markdown
Member

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.

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

Copy link
Copy Markdown
ContributorAuthor

It doesn't leave me feeling confident knowing that this cannot be reproduced in latest.

@jakobbotsch

Copy link
Copy Markdown
Member

How would you know that the problem cannot be reproduced in main? Once you understand the problem you might even be able to construct an example yourself.

@jakobbotsch

Copy link
Copy Markdown
Member

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
Actual: 0

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Once you understand the problem you might even be able to construct an example yourself.

That's the tricky part for this problem. I have no idea what I'm looking at as it's new to me.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

That new example, interestingly, it outputs 515 in e62cb64 .

@jakobbotsch

Copy link
Copy Markdown
Member

That new example, interestingly, it outputs 515 in e62cb64 .

Odd, I get the same codegen on main and e62cb64: a ldp w1, w0, [x0, #0x68] that incorrectly loads at 0x1A * 4.

@TIHan

TIHan commented Aug 15, 2023

Copy link
Copy Markdown
ContributorAuthor

@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 ldr/str pair optimization to ldp/stp respectively. The bug is that 'imm' and/or 'prevImm' are not "scaled" so it's using the wrong values for the comparisons. We should fix this, but we can fix it later.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

@dotnet/jit-contrib @BruceForstall@jakobbotsch this is ready, pending CI.

@TIHanTIHan changed the title Added regression test 85765[JIT] ARM64 - Temporary fix for ldp/stp optimizationsAug 15, 2023
Comment threadsrc/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs Outdated
@BruceForstall

Copy link
Copy Markdown
Contributor

No diffs

@BruceForstallBruceForstall left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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
TIHan merged commit 99a60c6 into dotnet:mainAug 16, 2023
@TIHan

Copy link
Copy Markdown
ContributorAuthor

/backport to release/8.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5881464622

@github-actions

Copy link
Copy Markdown
Contributor

@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

Copy link
Copy Markdown
ContributorAuthor

/backport to release/8.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5882707392

@jakobbotsch

Copy link
Copy Markdown
Member

@TIHan The test added here doesn't build -- seems like CI was red when this PR was merged.

@elinor-fung

Copy link
Copy Markdown
Member

@TIHan the test added doesn't build: src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs(59,27): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context [/__w/1/s/src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.csproj]

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Ok, will make a quick PR to fix this.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

#90698

@jkotas

Copy link
Copy Markdown
Member

I am going to revert this. This can be introducing number of other problems since the CI was all read when this was merged.

jkotas added a commit that referenced this pull request Aug 16, 2023
@TIHan

TIHan commented Aug 16, 2023

Copy link
Copy Markdown
ContributorAuthor

This is the same PR as this but with the test fix.

My fault for not checking.

@ghostghost locked as resolved and limited conversation to collaborators Sep 16, 2023
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR 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.

JIT: Invalid ldp optimization with locals

6 participants

@TIHan@jakobbotsch@BruceForstall@elinor-fung@jkotas@markples
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [JIT] ARM64 - Temporary fix for `ldp`/`stp` optimizations by TIHan · Pull Request #90534 · dotnet/runtime · GitHub
Skip to content

[JIT] ARM64 - Temporary fix for ldp/stp optimizations - #90534

Merged
TIHan merged 5 commits into
dotnet:mainfrom
TIHan:runtime_85765
Aug 16, 2023
Merged

[JIT] ARM64 - Temporary fix for ldp/stp optimizations#90534
TIHan merged 5 commits into
dotnet:mainfrom
TIHan:runtime_85765

Conversation

@TIHan

@TIHanTIHan commented Aug 14, 2023

Copy link
Copy Markdown
Contributor

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:

usingSystem;usingSystem.Runtime.CompilerServices;// Expected: 515// Actual: 0publicunsafeclassProgram{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]);}}

@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Aug 14, 2023
@ghostghost assigned TIHanAug 14, 2023
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

Resolves #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)
Author:TIHan
Assignees:-
Labels:

area-CodeGen-coreclr

Milestone:-

@jakobbotsch

jakobbotsch commented Aug 14, 2023

Copy link
Copy Markdown
Member

This repros up until #86491 was merged. Can you check out e62cb64 (the parent of #86491) and repro the problem there? With altjit and TC=0 I get the same codegen as in the issue on that commit.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

@jakobbotsch What did you do to determine which PR could repo this? Did you just do a bisect?

@jakobbotsch

Copy link
Copy Markdown
Member

@jakobbotsch What did you do to determine which PR could repo this? Did you just do a bisect?

Yes. I keep Core_Roots compiled for all JIT commits so that I can quickly do that.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Yes. I keep Core_Roots compiled for all JIT commits so that I can quickly do that.

That's a lot of Core_Roots :)

@TIHan

Copy link
Copy Markdown
ContributorAuthor

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

Copy link
Copy Markdown
Member

What if you mark M4 as NoInlining? It is not being inlined for me, but it seems it is inlined in your codegen.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

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

Copy link
Copy Markdown
Member

Marking it as NoInline I was able to reproduce it, but only on that commit.

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

Copy link
Copy Markdown
ContributorAuthor

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.

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

Copy link
Copy Markdown
Member

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.

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

Copy link
Copy Markdown
ContributorAuthor

It doesn't leave me feeling confident knowing that this cannot be reproduced in latest.

@jakobbotsch

Copy link
Copy Markdown
Member

How would you know that the problem cannot be reproduced in main? Once you understand the problem you might even be able to construct an example yourself.

@jakobbotsch

Copy link
Copy Markdown
Member

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
Actual: 0

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Once you understand the problem you might even be able to construct an example yourself.

That's the tricky part for this problem. I have no idea what I'm looking at as it's new to me.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

That new example, interestingly, it outputs 515 in e62cb64 .

@jakobbotsch

Copy link
Copy Markdown
Member

That new example, interestingly, it outputs 515 in e62cb64 .

Odd, I get the same codegen on main and e62cb64: a ldp w1, w0, [x0, #0x68] that incorrectly loads at 0x1A * 4.

@TIHan

TIHan commented Aug 15, 2023

Copy link
Copy Markdown
ContributorAuthor

@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 ldr/str pair optimization to ldp/stp respectively. The bug is that 'imm' and/or 'prevImm' are not "scaled" so it's using the wrong values for the comparisons. We should fix this, but we can fix it later.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

@dotnet/jit-contrib @BruceForstall@jakobbotsch this is ready, pending CI.

@TIHanTIHan changed the title Added regression test 85765[JIT] ARM64 - Temporary fix for ldp/stp optimizationsAug 15, 2023
Comment threadsrc/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs Outdated
@BruceForstall

Copy link
Copy Markdown
Contributor

No diffs

@BruceForstallBruceForstall left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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
TIHan merged commit 99a60c6 into dotnet:mainAug 16, 2023
@TIHan

Copy link
Copy Markdown
ContributorAuthor

/backport to release/8.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5881464622

@github-actions

Copy link
Copy Markdown
Contributor

@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

Copy link
Copy Markdown
ContributorAuthor

/backport to release/8.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5882707392

@jakobbotsch

Copy link
Copy Markdown
Member

@TIHan The test added here doesn't build -- seems like CI was red when this PR was merged.

@elinor-fung

Copy link
Copy Markdown
Member

@TIHan the test added doesn't build: src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs(59,27): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context [/__w/1/s/src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.csproj]

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Ok, will make a quick PR to fix this.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

#90698

@jkotas

Copy link
Copy Markdown
Member

I am going to revert this. This can be introducing number of other problems since the CI was all read when this was merged.

jkotas added a commit that referenced this pull request Aug 16, 2023
@TIHan

TIHan commented Aug 16, 2023

Copy link
Copy Markdown
ContributorAuthor

This is the same PR as this but with the test fix.

My fault for not checking.

@ghostghost locked as resolved and limited conversation to collaborators Sep 16, 2023
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR 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.

JIT: Invalid ldp optimization with locals

6 participants

@TIHan@jakobbotsch@BruceForstall@elinor-fung@jkotas@markples
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' [JIT] ARM64 - Temporary fix for `ldp`/`stp` optimizations by TIHan · Pull Request #90534 · dotnet/runtime · GitHub
Skip to content

[JIT] ARM64 - Temporary fix for ldp/stp optimizations - #90534

Merged
TIHan merged 5 commits into
dotnet:mainfrom
TIHan:runtime_85765
Aug 16, 2023
Merged

[JIT] ARM64 - Temporary fix for ldp/stp optimizations#90534
TIHan merged 5 commits into
dotnet:mainfrom
TIHan:runtime_85765

Conversation

@TIHan

@TIHanTIHan commented Aug 14, 2023

Copy link
Copy Markdown
Contributor

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:

usingSystem;usingSystem.Runtime.CompilerServices;// Expected: 515// Actual: 0publicunsafeclassProgram{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]);}}

@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Aug 14, 2023
@ghostghost assigned TIHanAug 14, 2023
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

Resolves #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)
Author:TIHan
Assignees:-
Labels:

area-CodeGen-coreclr

Milestone:-

@jakobbotsch

jakobbotsch commented Aug 14, 2023

Copy link
Copy Markdown
Member

This repros up until #86491 was merged. Can you check out e62cb64 (the parent of #86491) and repro the problem there? With altjit and TC=0 I get the same codegen as in the issue on that commit.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

@jakobbotsch What did you do to determine which PR could repo this? Did you just do a bisect?

@jakobbotsch

Copy link
Copy Markdown
Member

@jakobbotsch What did you do to determine which PR could repo this? Did you just do a bisect?

Yes. I keep Core_Roots compiled for all JIT commits so that I can quickly do that.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Yes. I keep Core_Roots compiled for all JIT commits so that I can quickly do that.

That's a lot of Core_Roots :)

@TIHan

Copy link
Copy Markdown
ContributorAuthor

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

Copy link
Copy Markdown
Member

What if you mark M4 as NoInlining? It is not being inlined for me, but it seems it is inlined in your codegen.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

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

Copy link
Copy Markdown
Member

Marking it as NoInline I was able to reproduce it, but only on that commit.

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

Copy link
Copy Markdown
ContributorAuthor

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.

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

Copy link
Copy Markdown
Member

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.

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

Copy link
Copy Markdown
ContributorAuthor

It doesn't leave me feeling confident knowing that this cannot be reproduced in latest.

@jakobbotsch

Copy link
Copy Markdown
Member

How would you know that the problem cannot be reproduced in main? Once you understand the problem you might even be able to construct an example yourself.

@jakobbotsch

Copy link
Copy Markdown
Member

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
Actual: 0

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Once you understand the problem you might even be able to construct an example yourself.

That's the tricky part for this problem. I have no idea what I'm looking at as it's new to me.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

That new example, interestingly, it outputs 515 in e62cb64 .

@jakobbotsch

Copy link
Copy Markdown
Member

That new example, interestingly, it outputs 515 in e62cb64 .

Odd, I get the same codegen on main and e62cb64: a ldp w1, w0, [x0, #0x68] that incorrectly loads at 0x1A * 4.

@TIHan

TIHan commented Aug 15, 2023

Copy link
Copy Markdown
ContributorAuthor

@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 ldr/str pair optimization to ldp/stp respectively. The bug is that 'imm' and/or 'prevImm' are not "scaled" so it's using the wrong values for the comparisons. We should fix this, but we can fix it later.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

@dotnet/jit-contrib @BruceForstall@jakobbotsch this is ready, pending CI.

@TIHanTIHan changed the title Added regression test 85765[JIT] ARM64 - Temporary fix for ldp/stp optimizationsAug 15, 2023
Comment threadsrc/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs Outdated
@BruceForstall

Copy link
Copy Markdown
Contributor

No diffs

@BruceForstallBruceForstall left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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
TIHan merged commit 99a60c6 into dotnet:mainAug 16, 2023
@TIHan

Copy link
Copy Markdown
ContributorAuthor

/backport to release/8.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5881464622

@github-actions

Copy link
Copy Markdown
Contributor

@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

Copy link
Copy Markdown
ContributorAuthor

/backport to release/8.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5882707392

@jakobbotsch

Copy link
Copy Markdown
Member

@TIHan The test added here doesn't build -- seems like CI was red when this PR was merged.

@elinor-fung

Copy link
Copy Markdown
Member

@TIHan the test added doesn't build: src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs(59,27): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context [/__w/1/s/src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.csproj]

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Ok, will make a quick PR to fix this.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

#90698

@jkotas

Copy link
Copy Markdown
Member

I am going to revert this. This can be introducing number of other problems since the CI was all read when this was merged.

jkotas added a commit that referenced this pull request Aug 16, 2023
@TIHan

TIHan commented Aug 16, 2023

Copy link
Copy Markdown
ContributorAuthor

This is the same PR as this but with the test fix.

My fault for not checking.

@ghostghost locked as resolved and limited conversation to collaborators Sep 16, 2023
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR 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.

JIT: Invalid ldp optimization with locals

6 participants

@TIHan@jakobbotsch@BruceForstall@elinor-fung@jkotas@markples
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [JIT] ARM64 - Temporary fix for `ldp`/`stp` optimizations by TIHan · Pull Request #90534 · dotnet/runtime · GitHub
Skip to content

[JIT] ARM64 - Temporary fix for ldp/stp optimizations - #90534

Merged
TIHan merged 5 commits into
dotnet:mainfrom
TIHan:runtime_85765
Aug 16, 2023
Merged

[JIT] ARM64 - Temporary fix for ldp/stp optimizations#90534
TIHan merged 5 commits into
dotnet:mainfrom
TIHan:runtime_85765

Conversation

@TIHan

@TIHanTIHan commented Aug 14, 2023

Copy link
Copy Markdown
Contributor

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:

usingSystem;usingSystem.Runtime.CompilerServices;// Expected: 515// Actual: 0publicunsafeclassProgram{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]);}}

@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Aug 14, 2023
@ghostghost assigned TIHanAug 14, 2023
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

Resolves #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)
Author:TIHan
Assignees:-
Labels:

area-CodeGen-coreclr

Milestone:-

@jakobbotsch

jakobbotsch commented Aug 14, 2023

Copy link
Copy Markdown
Member

This repros up until #86491 was merged. Can you check out e62cb64 (the parent of #86491) and repro the problem there? With altjit and TC=0 I get the same codegen as in the issue on that commit.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

@jakobbotsch What did you do to determine which PR could repo this? Did you just do a bisect?

@jakobbotsch

Copy link
Copy Markdown
Member

@jakobbotsch What did you do to determine which PR could repo this? Did you just do a bisect?

Yes. I keep Core_Roots compiled for all JIT commits so that I can quickly do that.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Yes. I keep Core_Roots compiled for all JIT commits so that I can quickly do that.

That's a lot of Core_Roots :)

@TIHan

Copy link
Copy Markdown
ContributorAuthor

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

Copy link
Copy Markdown
Member

What if you mark M4 as NoInlining? It is not being inlined for me, but it seems it is inlined in your codegen.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

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

Copy link
Copy Markdown
Member

Marking it as NoInline I was able to reproduce it, but only on that commit.

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

Copy link
Copy Markdown
ContributorAuthor

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.

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

Copy link
Copy Markdown
Member

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.

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

Copy link
Copy Markdown
ContributorAuthor

It doesn't leave me feeling confident knowing that this cannot be reproduced in latest.

@jakobbotsch

Copy link
Copy Markdown
Member

How would you know that the problem cannot be reproduced in main? Once you understand the problem you might even be able to construct an example yourself.

@jakobbotsch

Copy link
Copy Markdown
Member

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
Actual: 0

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Once you understand the problem you might even be able to construct an example yourself.

That's the tricky part for this problem. I have no idea what I'm looking at as it's new to me.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

That new example, interestingly, it outputs 515 in e62cb64 .

@jakobbotsch

Copy link
Copy Markdown
Member

That new example, interestingly, it outputs 515 in e62cb64 .

Odd, I get the same codegen on main and e62cb64: a ldp w1, w0, [x0, #0x68] that incorrectly loads at 0x1A * 4.

@TIHan

TIHan commented Aug 15, 2023

Copy link
Copy Markdown
ContributorAuthor

@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 ldr/str pair optimization to ldp/stp respectively. The bug is that 'imm' and/or 'prevImm' are not "scaled" so it's using the wrong values for the comparisons. We should fix this, but we can fix it later.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

@dotnet/jit-contrib @BruceForstall@jakobbotsch this is ready, pending CI.

@TIHanTIHan changed the title Added regression test 85765[JIT] ARM64 - Temporary fix for ldp/stp optimizationsAug 15, 2023
Comment threadsrc/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs Outdated
@BruceForstall

Copy link
Copy Markdown
Contributor

No diffs

@BruceForstallBruceForstall left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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
TIHan merged commit 99a60c6 into dotnet:mainAug 16, 2023
@TIHan

Copy link
Copy Markdown
ContributorAuthor

/backport to release/8.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5881464622

@github-actions

Copy link
Copy Markdown
Contributor

@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

Copy link
Copy Markdown
ContributorAuthor

/backport to release/8.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5882707392

@jakobbotsch

Copy link
Copy Markdown
Member

@TIHan The test added here doesn't build -- seems like CI was red when this PR was merged.

@elinor-fung

Copy link
Copy Markdown
Member

@TIHan the test added doesn't build: src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs(59,27): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context [/__w/1/s/src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.csproj]

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Ok, will make a quick PR to fix this.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

#90698

@jkotas

Copy link
Copy Markdown
Member

I am going to revert this. This can be introducing number of other problems since the CI was all read when this was merged.

jkotas added a commit that referenced this pull request Aug 16, 2023
@TIHan

TIHan commented Aug 16, 2023

Copy link
Copy Markdown
ContributorAuthor

This is the same PR as this but with the test fix.

My fault for not checking.

@ghostghost locked as resolved and limited conversation to collaborators Sep 16, 2023
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR 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.

JIT: Invalid ldp optimization with locals

6 participants

@TIHan@jakobbotsch@BruceForstall@elinor-fung@jkotas@markples
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); [JIT] ARM64 - Temporary fix for `ldp`/`stp` optimizations by TIHan · Pull Request #90534 · dotnet/runtime · GitHub
Skip to content

[JIT] ARM64 - Temporary fix for ldp/stp optimizations - #90534

Merged
TIHan merged 5 commits into
dotnet:mainfrom
TIHan:runtime_85765
Aug 16, 2023
Merged

[JIT] ARM64 - Temporary fix for ldp/stp optimizations#90534
TIHan merged 5 commits into
dotnet:mainfrom
TIHan:runtime_85765

Conversation

@TIHan

@TIHanTIHan commented Aug 14, 2023

Copy link
Copy Markdown
Contributor

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:

usingSystem;usingSystem.Runtime.CompilerServices;// Expected: 515// Actual: 0publicunsafeclassProgram{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]);}}

@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Aug 14, 2023
@ghostghost assigned TIHanAug 14, 2023
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

Resolves #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)
Author:TIHan
Assignees:-
Labels:

area-CodeGen-coreclr

Milestone:-

@jakobbotsch

jakobbotsch commented Aug 14, 2023

Copy link
Copy Markdown
Member

This repros up until #86491 was merged. Can you check out e62cb64 (the parent of #86491) and repro the problem there? With altjit and TC=0 I get the same codegen as in the issue on that commit.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

@jakobbotsch What did you do to determine which PR could repo this? Did you just do a bisect?

@jakobbotsch

Copy link
Copy Markdown
Member

@jakobbotsch What did you do to determine which PR could repo this? Did you just do a bisect?

Yes. I keep Core_Roots compiled for all JIT commits so that I can quickly do that.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Yes. I keep Core_Roots compiled for all JIT commits so that I can quickly do that.

That's a lot of Core_Roots :)

@TIHan

Copy link
Copy Markdown
ContributorAuthor

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

Copy link
Copy Markdown
Member

What if you mark M4 as NoInlining? It is not being inlined for me, but it seems it is inlined in your codegen.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

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

Copy link
Copy Markdown
Member

Marking it as NoInline I was able to reproduce it, but only on that commit.

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

Copy link
Copy Markdown
ContributorAuthor

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.

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

Copy link
Copy Markdown
Member

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.

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

Copy link
Copy Markdown
ContributorAuthor

It doesn't leave me feeling confident knowing that this cannot be reproduced in latest.

@jakobbotsch

Copy link
Copy Markdown
Member

How would you know that the problem cannot be reproduced in main? Once you understand the problem you might even be able to construct an example yourself.

@jakobbotsch

Copy link
Copy Markdown
Member

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
Actual: 0

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Once you understand the problem you might even be able to construct an example yourself.

That's the tricky part for this problem. I have no idea what I'm looking at as it's new to me.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

That new example, interestingly, it outputs 515 in e62cb64 .

@jakobbotsch

Copy link
Copy Markdown
Member

That new example, interestingly, it outputs 515 in e62cb64 .

Odd, I get the same codegen on main and e62cb64: a ldp w1, w0, [x0, #0x68] that incorrectly loads at 0x1A * 4.

@TIHan

TIHan commented Aug 15, 2023

Copy link
Copy Markdown
ContributorAuthor

@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 ldr/str pair optimization to ldp/stp respectively. The bug is that 'imm' and/or 'prevImm' are not "scaled" so it's using the wrong values for the comparisons. We should fix this, but we can fix it later.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

@dotnet/jit-contrib @BruceForstall@jakobbotsch this is ready, pending CI.

@TIHanTIHan changed the title Added regression test 85765[JIT] ARM64 - Temporary fix for ldp/stp optimizationsAug 15, 2023
Comment threadsrc/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs Outdated
@BruceForstall

Copy link
Copy Markdown
Contributor

No diffs

@BruceForstallBruceForstall left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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
TIHan merged commit 99a60c6 into dotnet:mainAug 16, 2023
@TIHan

Copy link
Copy Markdown
ContributorAuthor

/backport to release/8.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5881464622

@github-actions

Copy link
Copy Markdown
Contributor

@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

Copy link
Copy Markdown
ContributorAuthor

/backport to release/8.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/8.0: https://github.com/dotnet/runtime/actions/runs/5882707392

@jakobbotsch

Copy link
Copy Markdown
Member

@TIHan The test added here doesn't build -- seems like CI was red when this PR was merged.

@elinor-fung

Copy link
Copy Markdown
Member

@TIHan the test added doesn't build: src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.cs(59,27): error CS0214: Pointers and fixed size buffers may only be used in an unsafe context [/__w/1/s/src/tests/JIT/Regression/JitBlue/Runtime_85765/Runtime_85765.csproj]

@TIHan

Copy link
Copy Markdown
ContributorAuthor

Ok, will make a quick PR to fix this.

@TIHan

Copy link
Copy Markdown
ContributorAuthor

#90698

@jkotas

Copy link
Copy Markdown
Member

I am going to revert this. This can be introducing number of other problems since the CI was all read when this was merged.

jkotas added a commit that referenced this pull request Aug 16, 2023
@TIHan

TIHan commented Aug 16, 2023

Copy link
Copy Markdown
ContributorAuthor

This is the same PR as this but with the test fix.

My fault for not checking.

@ghostghost locked as resolved and limited conversation to collaborators Sep 16, 2023
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR 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.

JIT: Invalid ldp optimization with locals

6 participants

@TIHan@jakobbotsch@BruceForstall@elinor-fung@jkotas@markples