Uh oh!
There was an error while loading. Please reload this page.
Ensure that TryGetContainableHWIntrinsicOp is non-mutating - #79363
Conversation
ghost
commented
Dec 7, 2022
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsThis removes a possible mutating side-effect from This helps ensure accidental side effects don't happen and improves codegen for cases like the following: Unsafe.SkipInit(outthis);Vector128<float>x=Vector128.Create(m11,m12,m13,m14);x.StoreUnsafe(refM11);Vector128<float>y=Vector128.Create(m21,m22,m23,m24);y.StoreUnsafe(refM21);Vector128<float>z=Vector128.Create(m31,m32,m33,m34);z.StoreUnsafe(refM31);Vector128<float>w=Vector128.Create(m41,m42,m43,m44);w.StoreUnsafe(refM41);Before we generated: 3809cmp byte ptr [rcx],clC4E37121C210 vinsertps xmm0,xmm1,xmm2,16C4E37921C320 vinsertps xmm0,xmm0,xmm3,32C5FA104C2428 vmovssxmm1, dword ptr [rsp+28H]C4E37921C130 vinsertps xmm0,xmm0,xmm1,48C5F81101 vmovups xmmword ptr [rcx],xmm0C5FA10442430 vmovssxmm0, dword ptr [rsp+30H]C5FA104C2438 vmovssxmm1, dword ptr [rsp+38H]C4E37921C110 vinsertps xmm0,xmm0,xmm1,16C5FA104C2440 vmovssxmm1, dword ptr [rsp+40H]C4E37921C120 vinsertps xmm0,xmm0,xmm1,32C5FA104C2448 vmovssxmm1, dword ptr [rsp+48H]C4E37921C130 vinsertps xmm0,xmm0,xmm1,48C5F8114110 vmovups xmmword ptr [rcx+10H],xmm0C5FA10442450 vmovssxmm0, dword ptr [rsp+50H]C5FA104C2458 vmovssxmm1, dword ptr [rsp+58H]C4E37921C110 vinsertps xmm0,xmm0,xmm1,16C5FA104C2460 vmovssxmm1, dword ptr [rsp+60H]C4E37921C120 vinsertps xmm0,xmm0,xmm1,32C5FA104C2468 vmovssxmm1, dword ptr [rsp+68H]C4E37921C130 vinsertps xmm0,xmm0,xmm1,48C5F8114120 vmovups xmmword ptr [rcx+20H],xmm0C5FA10442470 vmovssxmm0, dword ptr [rsp+70H]C5FA104C2478 vmovssxmm1, dword ptr [rsp+78H]C4E37921C110 vinsertps xmm0,xmm0,xmm1,16C5FA108C2480000000 vmovssxmm1, dword ptr [rsp+80H]C4E37921C120 vinsertps xmm0,xmm0,xmm1,32C5FA108C2488000000 vmovssxmm1, dword ptr [rsp+88H]C4E37921C130 vinsertps xmm0,xmm0,xmm1,48C5F8114130 vmovups xmmword ptr [rcx+30H],xmm0Now we generate 3809cmp byte ptr [rcx],clC4E37121C210 vinsertps xmm0,xmm1,xmm2,16C4E37921C320 vinsertps xmm0,xmm0,xmm3,32C4E3792144242830 vinsertps xmm0,xmm0, dword ptr [rsp+28H],48C5F81101 vmovups xmmword ptr [rcx],xmm0C5FA10442430 vmovssxmm0, dword ptr [rsp+30H]C4E3792144243810 vinsertps xmm0,xmm0, dword ptr [rsp+38H],16C4E3792144244020 vinsertps xmm0,xmm0, dword ptr [rsp+40H],32C4E3792144244830 vinsertps xmm0,xmm0, dword ptr [rsp+48H],48C5F8114110 vmovups xmmword ptr [rcx+10H],xmm0C5FA10442450 vmovssxmm0, dword ptr [rsp+50H]C4E3792144245810 vinsertps xmm0,xmm0, dword ptr [rsp+58H],16C4E3792144246020 vinsertps xmm0,xmm0, dword ptr [rsp+60H],32C4E3792144246830 vinsertps xmm0,xmm0, dword ptr [rsp+68H],48C5F8114120 vmovups xmmword ptr [rcx+20H],xmm0C5FA10442470 vmovssxmm0, dword ptr [rsp+70H]C4E3792144247810 vinsertps xmm0,xmm0, dword ptr [rsp+78H],16C4E3792184248000000020 vinsertps xmm0,xmm0, dword ptr [rsp+80H],32C4E3792184248800000030 vinsertps xmm0,xmm0, dword ptr [rsp+88H],48C5F8114130 vmovups xmmword ptr [rcx+30H],xmm0
|
tannergooding
commented
Dec 7, 2022
Ideally we'd be able to improve this even more and recognize However, I've been told this is complicated since we apparently do not surface whether or not a given |
tannergooding
commented
Dec 8, 2022
CC. @dotnet/jit-contrib |
BruceForstall
commented
Dec 8, 2022
Why are there some regressions? |
tannergooding
commented
Dec 9, 2022
@BruceForstall, looks like possibly a bug in diff reporting? If I had to guess, this is an issue with a peephole optimization not correctly impacting the computed instruction size. If we look at 173746.dasm from
We'll see - ;; size=91 bbWeight=1 PerfScore 18.08+ ;; size=97 bbWeight=1 PerfScore 18.08For Latter instruction groups largely just change the IG block number they jump to and occasionally insert new alignment bytes, but even when its a diff of 1 alignment byte, they often have significantly larger size inscreases measured. |
tannergooding
commented
Dec 9, 2022
@BruceForstall, @kunalspathak actually after looking at the raw disassembly (which includes the codegen bytes), this is the alignment code pessimizing SIMD codegen. Basically, if we decide to emit alignment blocks at all, then SIMD codegen gets forced to always emit the 3-byte encoding rather than the more optimal 2-byte encoding: https://github.com/dotnet/runtime/blob/main/src/coreclr/jit/emitxarch.cpp#L1560-L1569 This can mean otherwise profitable changes can appear to be no longer profitable in any method that is SIMD or floating-point heavy. |
kunalspathak
commented
Dec 9, 2022
That is unfortunately true. We could potentially have a heuristic to not |
tannergooding
commented
Dec 9, 2022
I'm going to see how easy it is to "fix" the size estimation to not statically return 3. The biggest "missing" piece should really be the checks on which registers are used. |
tannergooding
commented
Dec 9, 2022
I don't think its worth blocking this PR on that change, however. This change is a net positive to the number of instructions emitted with the "regressions" being an external factor based on loop alignment. |
tannergooding
commented
Dec 14, 2022
No changes, just rerunning CI and getting updated diffs now that #79478 is merged. I expect the SPMI diffs to look even better. Plan on merging after those get back, assuming nothing unexpected crops up. |
tannergooding
commented
Dec 14, 2022
Indeed better diffs But shows a couple small regressions on |
tannergooding
commented
Dec 15, 2022
@BruceForstall, resolved all the regressions with the last two commits. Since they were a little more complex, it might be worth a second review/sign-off: The first handles the FMA case by ensuring we recheck containment after removing the The second was a little more complex and involves |
This removes a possible mutating side-effect from
TryGetContainableHWIntrinsicOpby allowingCreateScalarUnsafeto be directly contained.This helps ensure accidental side effects don't happen and improves codegen for cases like the following:
Before we generated:
Now we generate