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
