JIT: fold CAST<small>(COMMA(se, IND<small-same-size>))#129387
JIT: fold CAST<small>(COMMA(se, IND<small-same-size>))#129387AndyAyersMS wants to merge 1 commit into
CAST<small>(COMMA(se, IND<small-same-size>))#129387Conversation
Extend fgOptimizeCast to look through GT_COMMA wrappers when matching the existing small-int IND retyping. This lets `(sbyte)span[i]` collapse from a zero-extending load followed by a sign-extending cast into a single `movsx` load, instead of the previous `movzx; movsx` sequence. Fixes dotnet#69472.
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
There was a problem hiding this comment.
Pull request overview
This PR updates the CoreCLR JIT’s fgOptimizeCast to look through GT_COMMA wrappers when applying the existing “small-int indirection retyping” optimization, and adds a JIT regression test under src/tests/JIT/Regression/JitBlue to exercise signed/unsigned small-int cast scenarios (including the ReadOnlySpan<T> indexer shape that commonly introduces a COMMA).
Changes:
- Extend
fgOptimizeCastto usegtEffectiveVal()so it can match and retype comma-wrappedGT_IND/GT_LCL_FLDnodes. - Add new JitBlue regression test
Runtime_69472and include it inRegression_ro_2.csproj.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/coreclr/jit/morph.cpp | Teach cast folding to look through GT_COMMA and retype the effective indirection. |
| src/tests/JIT/Regression/Regression_ro_2.csproj | Include the new regression test source file in the merged runner project. |
| src/tests/JIT/Regression/JitBlue/Runtime_69472/Runtime_69472.cs | Add regression coverage for small-int cast folding shapes and signed/unsigned combinations. |
| effectiveSrc->ChangeType(castToType); | ||
|
|
||
| // Propagate the new type up through any COMMA wrappers so that the | ||
| // tree's type accurately describes the value being produced. | ||
| for (GenTree* cur = src; cur != effectiveSrc; cur = cur->AsOp()->gtOp2) | ||
| { | ||
| cur->ChangeType(castToType); | ||
| } | ||
|
|
||
| src->SetVNsFromNode(cast); | ||
|
|
||
| return src; |
| // `(sbyte)span[i]` which previously emitted a zero-extending load followed by | ||
| // a sign-extending cast and should now collapse to a single `movsx` (or | ||
| // equivalently `movzx`) load. |
| for (int v = 0; v <= 0xFFFF; v++) | ||
| { | ||
| ushort uw = (ushort)v; | ||
| short sw = unchecked((short)v); | ||
| ushort[] ua = new[] { uw }; | ||
| short[] sa = new[] { sw }; | ||
|
|
| for (GenTree* cur = src; cur != effectiveSrc; cur = cur->AsOp()->gtOp2) | ||
| { | ||
| cur->ChangeType(castToType); | ||
| } |
There was a problem hiding this comment.
Doesn't ChangeType do this already if called on the right node?
| <Compile Include="JitBlue\Runtime_128801\Runtime_128801.cs" /> | ||
| <Compile Include="JitBlue\Runtime_129076\Runtime_129076.cs" /> | ||
| <Compile Include="JitBlue\Runtime_129176\Runtime_129176.cs" /> | ||
| <Compile Include="JitBlue\Runtime_69472\Runtime_69472.cs" /> |
There was a problem hiding this comment.
Should this be a regression test?
Extend fgOptimizeCast to look through GT_COMMA wrappers when matching the existing small-int IND retyping. This lets
(sbyte)span[i]collapse from a zero-extending load followed by a sign-extending cast into a singlemovsxload, instead of the previousmovzx; movsxsequence.Fixes #69472.