RFR: 8305524: AArch64: Fix arraycopy issue on SVE caused by matching rule vmask_gen_sub

Pengfei Li pli at openjdk.org
Fri Apr 7 07:28:55 UTC 2023


>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.

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

Commit messages:
 - 8305524: AArch64: Fix arraycopy issue on SVE caused by matching rule vmask_gen_sub

Changes: https://git.openjdk.org/jdk/pull/13382/files
 Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=13382&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8305524
  Stats: 62 lines in 4 files changed: 52 ins; 0 del; 10 mod
  Patch: https://git.openjdk.org/jdk/pull/13382.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/13382/head:pull/13382

PR: https://git.openjdk.org/jdk/pull/13382


More information about the hotspot-compiler-dev mailing list