RFR: 8367292: VectorAPI: Optimize VectorMask.fromLong/toLong() for SVE [v6]
Xiaohong Gong
xgong at openjdk.org
Fri Nov 7 05:41:37 UTC 2025
> The current implementations of `VectorMask.fromLong()` and `toLong()` on AArch64 SVE are inefficient. SVE does not support naive predicate instructions for these operations. Instead, they are implemented with vector instructions, but the output/input of `fromLong/toLong` are defined as masks with predicate registers on SVE architectures.
>
> For `toLong()`, the current implementation generates a vector mask stored in a vector register with bool type first, then converts the vector to predicate layout. For `fromLong()`, the opposite conversion is needed at the start of codegen.
>
> These conversions are expensive and are implemented in the IR backend codegen, which is inefficient. The performance impact is significant on SVE architectures.
>
> This patch optimizes the implementation by leveraging two existing C2 IRs (`VectorLoadMask/VectorStoreMask`) that can handle the conversion efficiently. By splitting this work at the mid-end IR level, we align with the current IR pattern used on architectures without predicate features (like AArch64 Neon) and enable sharing of existing common IR optimizations.
>
> It also modifies the Vector API jtreg tests for well testing. Here is the details:
>
> 1) Fix the smoke tests of `fromLong/toLong` to make sure these APIs are tested actually. These two APIs are not well tested before. Because in the original test, the C2 IRs for `fromLong` and `toLong` are optimized out completely by compiler due to following IR identity:
>
> VectorMaskToLong (VectorLongToMask l) => l
>
> Besides, an additional warmup loop is necessary to guarantee the APIs are compiled by C2.
>
> 2) Refine existing IR tests to verify the expected IR patterns after this patch. Also changed to use the exact required cpu feature on AArch64 for these ops. `fromLong` requires "svebitperm" instead of "sve2".
>
> Performance shows significant improvement on NVIDIA's Grace CPU.
>
> Here is the performance data with `-XX:UseSVE=2`:
>
> Benchmark bits inputs Mode Unit Before After Gain
> MaskQueryOperationsBenchmark.testToLongByte 128 1 thrpt ops/ms 322151.976 1318576.736 4.09
> MaskQueryOperationsBenchmark.testToLongByte 128 2 thrpt ops/ms 322187.144 1315736.931 4.08
> MaskQueryOperationsBenchmark.testToLongByte 128 3 thrpt ops/ms 322213.330 1353272.882 4.19
> MaskQueryOperationsBenchmark.testToLongInt 128 1 thrpt ops/ms 1009426.292 1339834.833 1.32
> MaskQueryOperationsBenchmark.testToLongInt 128 2 thrpt ops/ms 101031...
Xiaohong Gong has updated the pull request incrementally with one additional commit since the last revision:
Revert smoke test changes
-------------
Changes:
- all: https://git.openjdk.org/jdk/pull/27481/files
- new: https://git.openjdk.org/jdk/pull/27481/files/40c2df04..97ba1748
Webrevs:
- full: https://webrevs.openjdk.org/?repo=jdk&pr=27481&range=05
- incr: https://webrevs.openjdk.org/?repo=jdk&pr=27481&range=04-05
Stats: 181 lines in 32 files changed: 0 ins; 75 del; 106 mod
Patch: https://git.openjdk.org/jdk/pull/27481.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/27481/head:pull/27481
PR: https://git.openjdk.org/jdk/pull/27481
More information about the hotspot-compiler-dev
mailing list