RFR: 8305524: AArch64: Fix arraycopy issue on SVE caused by matching rule vmask_gen_sub
Xiaohong Gong
xgong at openjdk.org
Wed Apr 12 02:41:40 UTC 2023
On Fri, 7 Apr 2023 07:21:05 GMT, Pengfei Li <pli at openjdk.org> wrote:
> From recent tests, we find that `System.arraycopy()` call with a negated variable as its length argument does not perform the copy. This issue is reproducible by below test case on AArch64 platforms with SVE.
>
>
> public class Test {
> static char[] src = {'A', 'A', 'A', 'A', 'A'};
> static char[] dst = {'B', 'B', 'B', 'B', 'B'};
>
> static void copy(int nlen) {
> System.arraycopy(src, 0, dst, 0, -nlen);
> }
>
> public static void main(String[] args) {
> for (int i = 0; i < 25000; i++) {
> copy(0);
> }
> copy(-5);
> for (char c : dst) {
> if (c != 'A') {
> throw new RuntimeException("Wrong value!");
> }
> }
> System.out.println("PASS");
> }
> }
>
> /*
> $ java -Xint Test
> PASS
> $ java -Xbatch Test
> Exception in thread "main" java.lang.RuntimeException: Wrong value!
> at Test.main(Test.java:16)
> */
>
>
> Cause of this is a new AArch64 matching rule `vmask_gen_sub` introduced by JDK-8293198. It matches `VectorMaskGen (SubL src1 src2)` on AArch64 platforms with SVE and generates SVE `whilelo` instructions. Current C2 compiler uses a technique called "partial inlining" to vectorize small array copy operations by generating vector masks. In above test case, a negated variable `-nlen` is used as the length argument of the call and `-nlen` has a small positive value, so it is a "partial inlining" case. C2 will transform the ideal graph to `VectorMaskGen (SubL 0 nlen)` and eventually output an instruction of `whilelo p0, nlen, zr` which always generates an all-false vector mask. That's why arraycopy does nothing.
>
> The problem of that matching rule is that it regards inputs `src1` and `src2` as unsigned long integers but they can be signed in use cases of arraycopy. To fix the issue, this patch replaces `whilelo` instruction by `whilelt` in that rule as well as some other places.
>
> We tested tier1~3 on SVE and found no new failure. A jtreg math library test jdk/internal/math/FloatingDecimal/TestFloatingDecimal.java which fails on SVE before can pass now.
Thanks for the fixing! Looks good to me.
-------------
Marked as reviewed by xgong (Committer).
PR Review: https://git.openjdk.org/jdk/pull/13382#pullrequestreview-1380346111
More information about the hotspot-compiler-dev
mailing list