On Thu, 4 Jun 2026 08:16:18 GMT, Eric Fang <[email protected]> wrote:

> This PR continues the JDK-8384571 [1] work by further optimizing 
> Blend-related IR patterns. It adds the factoring optimization that pulls a 
> shared operand out of two matching lane-wise binary ops fed into a 
> `VectorBlend`:
> 
>   (VectorBlend (op A C) (op B C) M) => (op (VectorBlend A B M) C)
> 
> 
> For commutative ops the common operand may be in either position; for 
> non-commutative ops it must appear in the same slot in both inner ops.
> 
> Shifts and rotates are not factored when the common operand sits in the count 
> slot, since that turns a constant shift/rotate amount into a non-constant one 
> which is not guaranteed to be a win in codegen.
> 
> Also extends `MulVLNode::has_int_inputs` / `has_uint_inputs` to peek through 
> `VectorBlend` so the `MulVL -> vmuldq/vmuludq` narrowing on x86 keeps working 
> after the factoring runs.
> 
> The `factorMulLong` benchmark exposed a performance issue with the rule 
> `vmulL_neon`: The encoder lowers `MulVL` to per-lane `GPR extract -> scalar 
> mul -> mov dst.D[i]`. The first `mov` inherits a partial-write merge 
> dependency on the old `dst`, and if the register allocator coalesces `dst` 
> with `src1/src2` the subsequent `umov` for lane 1 must wait for that merge to 
> retire. This serialises the two scalar `muls` within an iteration and across 
> unrolled iterations. This PR fix the issue by forcing `dst` into a fresh 
> register to breaks the chain.
> 
> This PR also extends the existing JTReg and JMH tests for `VectorBlend`. All 
> tests (tier1, tier2, and tier3) passed on AArch64 and X86 platforms.
> 
> JMH benchmark test results:
> 
> On a Nvidia Grace (Neoverse-V2) machine with 128-bit SVE2:
> 
> Benchmark                     Unit    Before  Err     After   Err         
> Uplift
> factorAddFloat                    ops/ms      2726.9  1.1     7790.8  12.1    
> 2.9
> factorAddInt              ops/ms      3383.4  3.9     7778.3  19.7    2.3
> factorAndInt              ops/ms      3386.8  2.1     436377  4806.1  128.8
> factorCompressBitsInt ops/ms  1455.7  1.0     2244.7  0.7         1.5
> factorDivFloat                    ops/ms      1084.9  1.2     1777.4  0.8     
>     1.6
> factorExpandBitsLong  ops/ms  1455.6  1.7     2237.7  1.4         1.5
> factorLShiftInt                   ops/ms      1923.7  2.4     3518.7  3.6     
>     1.8
> factorMaxDouble                   ops/ms      2712.8  1.6     7718.3  4.9     
>     2.8
> factorMinFloat                    ops/ms      2725.0  4.7     7778.5  13.5    
> 2.9
> factorMulLong             ops/ms      1427.3  0.6     2773.2  3.4         1.9
> factorOrLong              ops/ms      3377.3  3.0     472138  2687.2  139.8
> factorRolInt              ops/ms      1188.0  1.7     1187.9  0.4         1.0
> factorSAddInt             ops/ms      3384.8  3.3     7769.1  4.1         2.3
> factorSSubInt             ops/ms      3387.4  8.2     7790.4  12.5    2.3
> factorSubDouble                   ops/ms      2717.7  3.1     7711.4  2.6     
>     2...

LGTM. Any reason why the float/double tests are not in the first PR?

-------------

PR Review: https://git.openjdk.org/jdk/pull/31379#pullrequestreview-4602350987

Reply via email to