Incorrect calculation result due to C2 auto-vectorization of short-to-int multiplications

XMLWordPrintable

      ADDITIONAL SYSTEM INFORMATION :
      Software:
          System Software Overview:
            System Version: Ubuntu 22.04.4 LTS
            Kernel Version: 4.15.0-45-generic
            Boot Volume: overlay
            Boot Mode: Legacy BIOS

      Hardware:
          Hardware Overview:
            Chip: Intel(R) Xeon(R) CPU E5-2640 v4 @ 2.40GHz
            Total Number of Cores: 40 (10 physical x 2 logical)
            Memory: 125Gi

      A DESCRIPTION OF THE PROBLEM :
      A miscompilation is observed in the HotSpot C2 compiler when a loop contains arithmetic operations involving short-to-int widening and non-contiguous stores into the result array.
      In the provided reproducer, the method test is first executed during class initialization (interpreted mode) to generate a "golden" result. Subsequently, the method is called in a loop to trigger JIT compilation. After C2 optimization kicks in, the results produced by the optimized code differ from the golden result, triggering a RuntimeException.

      REGRESSION : Java version that customer using for 17.0.18, 21.0.10



      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. javac Test.java.
      2. java -Xcomp Test

      ---------- BEGIN SOURCE ----------
      public class Test {
          static final int RANGE = 1024 * 16;
          static final int ITER = (RANGE / 2) - 1;
          static short[] sArr1 = new short[RANGE];
          static short[] sArr2 = new short[RANGE];
          static final int[] GOLDEN_K;

          static {
              for (int i = 0; i < RANGE; i++) {
                  sArr1[i] = ((short) (i));
                  sArr2[i] = ((short) (i));
              }
              GOLDEN_K = test(generate());
          }

          public static void main(String[] args) {
              for (int i = 0; i < ITER; i++) {
                  compare(test(generate()), GOLDEN_K, "test");
              }
          }

          public static int[] generate() {
              int[] a = new int[ITER];
              for (int i = 0; i < ITER; i++) {
                  a[i] = 1;
              }
              return a;
          }

          public static void compare(int[] out, int[] golden, String name) {
              long err = 0;
              for (int i = 0; i < ITER; i++) {
                  if (out[i] != golden[i]) {
                      err++;
                  }
              }
              if (err > 0) {
                  throw new RuntimeException("errors: " + err);
              }
          }

          public static int[] test(int[] out) {
              for (int i = 0; i < (ITER - 2); i += 4) {
                  out[i + 0] = (sArr1[(2 * i) + 0] * sArr2[(2 * i) + 1]) + (sArr1[(2 * i) + 1] * sArr2[(2 * i) + 0]);
                  out[i + 1] = (sArr1[(2 * i) + 2] * sArr2[(2 * i) + 2]) + (sArr1[(2 * i) + 3] * sArr2[(2 * i) + 3]);
              }
              return out;
          }
      }
      ---------- END SOURCE ----------

      FREQUENCY :
      ALWAYS

            Assignee:
            Unassigned
            Reporter:
            Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: