Avoid repeated SIMD mask proof traversal in value numbering - #134530
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Skip repeated scalar math and hardware-intrinsic evaluation when all operand VN pairs match, following VNPairForFunc. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
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. |
| ValueNum normalCVN = vnStore->EvalHWIntrinsicFunUnary(tree, func, op1vnp.GetConservative(), | ||
| resultTypeVNPair.GetConservative()); | ||
| ValueNum normalCVN; | ||
|
|
||
| if (op1vnp.BothEqual()) | ||
| { | ||
| normalCVN = normalLVN; | ||
| } | ||
| else | ||
| { | ||
| normalCVN = vnStore->EvalHWIntrinsicFunUnary(tree, func, op1vnp.GetConservative(), | ||
| resultTypeVNPair.GetConservative()); | ||
| } |
There was a problem hiding this comment.
Finally, this is other redundant work we were doing, where most other VN functions have a similar BothEqual check to avoid such redundancy
There was a problem hiding this comment.
We do this everywhere else I think, feels weird to expand only for rarely used stuff. You already added the budget check, do we still need these verbose fast paths?
There was a problem hiding this comment.
We do this everywhere else I think, feels weird to expand only for rarely used stuff
Not sure what you mean? We pretty consistently use BothEqual() to avoid duplicating work and you can see it in all the VNPairFor* helpers, including VNPairForFunc. HWIntrinsics were the odd one out by doing the work twice instead.
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
Core JIT changes lack full JIT, ARM64, and SuperPMI validation.
Review effort: Lite
Findings: None
What changed in this PR
Improves JIT SIMD value-numbering performance by caching mask proofs, bounding recursion, and reusing intrinsic evaluations.
Changes:
- Adds per-query SIMD mask-proof caching and depth limiting.
- Avoids unnecessary mask analysis for mismatched constants.
- Reuses intrinsic evaluations when operand VNs match.
- Adds a regression test for exponential traversal.
| File | Description |
|---|---|
src/tests/JIT/Regression_2/Runtime_134487/Runtime_134487.csproj |
Configures the regression test and disables AVX-512. |
src/tests/JIT/Regression_2/Runtime_134487/Runtime_134487.cs |
Adds the unrolled SIMD mask-chain regression test. |
src/coreclr/jit/valuenum.h |
Declares cached mask analysis and VN-pair evaluation logic. |
src/coreclr/jit/valuenum.cpp |
Implements mask caching, depth limiting, constant gating, and evaluation reuse. |
Summary
Avoid exponential traversal of shared value-number graphs when proving that a SIMD value is a per-element mask. A short unrolled chain can repeatedly reference the same mask VN along multiple paths, causing the old proof to revisit the same subgraphs exponentially.
Cache successful compound mask proofs within each query and retain a 64-level recursion cutoff. Check the cache before the cutoff so already-proven values remain usable at the depth boundary. Also check the comparison constant before attempting the mask proof.
A separate follow-up commit reuses intrinsic evaluation results when every operand has identical liberal and conservative VNs. This follows the existing
VNPairForFuncpattern for scalar math and unary/binary/ternary hardware intrinsics; distinct operand pairs still receive separate evaluations.Performance
Windows x64 Release JIT, AVX-512 disabled. Fresh methods are compiled with
RuntimeHelpers.PrepareMethod; IL generation and execution are outside the timed region. Execution afterward checks the result.For the 25-step mask chain, median compilation time drops from 5.59 seconds to approximately 0.29 ms. The original proof expands roughly 134 million calls over just 52 relevant unique VNs (analytically derived counts).
The separate liberal/conservative reuse change showed no additional improvement distinguishable from noise in repeated local measurements.
Validation
No ARM64 execution, full JIT test suite, or SuperPMI validation was performed.
Resolves #134487
Note
This PR description was drafted with GitHub Copilot.