Repository navigation
JIT: Forward comparisons with live-out boolean results - #135984
dhartglassMSFT wants to merge 5 commits into
Conversation
|
Azure Pipelines: Successfully started running 5 pipeline(s). 11 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
|
@dotnet/jit-contrib @EgorBo |
| unsigned const lclNum = def->AsLclVar()->GetLclNum(); | ||
| LclVarDsc* const varDsc = lvaGetDesc(lclNum); | ||
| if (!varDsc->lvTracked || varDsc->IsAddressExposed() || varDsc->lvPinned || varDsc->lvIsStructField || | ||
| varDsc->IsLiveInOutOfHandler() || (genActualType(varDsc->TypeGet()) != TYP_INT)) |
There was a problem hiding this comment.
Not sure I understand the limitation on varDsc->lvIsStructField and genActualType(varDsc->TypeGet()) != TYP_INT). Also, IsLiveInOutOfHandler feels redudant - Liveness already adds what exception handlers need to a block's live-in set
|
|
||
| if (cond->OperIs(GT_EQ)) | ||
| { | ||
| bool const reversed = gtTryReverseCond(compare); |
There was a problem hiding this comment.
am I missing something - why do we reverse only EQ here?
|
This feels like it's doing what |
Method:
bool M1(object o) => o != null && (o is int or uint or long);Intro block has code with an extra compare like cmp+cset+cbz (null check, write result of null check to local, compare and branch on local). The first cmp is needed because the local which receives the null check is live in later blocks.
To fix, JIT will look for shapes like this during forwardsub, replace the branch with the null check itself, and store a constant to the null-check-local along the path its used.
TPDiff reports +0.01%.
Diffs from motivating example:
x64
ARM64
Full arch diff results. I'm still looking through regressions. Some are cases of loop cloning being enabled, or changes in lsra.