Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8285985

Vector.reinterpretShape fails to preserve bits when handling signalling NaNs

XMLWordPrintable

      If you run Vector reinterpret tests on lower SSEs in x86_32 builds like below, then it would fail (added diagnostic data by hand):

      $ CONF=linux-x86-server-fastdebug make run-test TEST=compiler/vectorapi/reshape/TestVectorReinterpret.java TEST_VM_OPTS="-XX:UseAVX=0 -XX:UseSSE=0"

      Custom Run Test: @Run: runB64toF64 - @Test: testB64toF64:
      compiler.lib.ir_framework.shared.TestRunException: There was an error while invoking @Run method public static void compiler.vectorapi.reshape.tests.TestVectorRebracket.runB64toF64() throws java.lang.Throwable
      at compiler.lib.ir_framework.test.CustomRunTest.invokeTest(CustomRunTest.java:162)
      at compiler.lib.ir_framework.test.AbstractTest.run(AbstractTest.java:99)
      at compiler.lib.ir_framework.test.CustomRunTest.run(CustomRunTest.java:89)
      at compiler.lib.ir_framework.test.TestVM.runTests(TestVM.java:818)
      at compiler.lib.ir_framework.test.TestVM.start(TestVM.java:249)
      at compiler.lib.ir_framework.test.TestVM.main(TestVM.java:164)
      Caused by: java.lang.reflect.InvocationTargetException
      at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
      at java.base/java.lang.reflect.Method.invoke(Method.java:578)
      at compiler.lib.ir_framework.test.CustomRunTest.invokeTest(CustomRunTest.java:159)
      ... 5 more
      Caused by: java.lang.RuntimeException: at byte 2 (8):
      Expected = 3e, dc, 88, 7f, 95, c6, c4, fa,
        Actual = 3e, dc, c8, 7f, 95, c6, c4, fa,
      expected=NaN actual=NaN
      expected=7f88dc3e actual=7fc8dc3e

      The underlying problem is that random data generator produces signalling NaN (7f88dc3e), but the code involves reinterpreting the vector through the floating point stores, which, when x87 is involved, converts the value into quiet NaN (7fc8dc3e).

      I see the Javadoc for Vector.reinterpretShape says:

      ```
           * Transforms this vector to a vector of the given species of
           * element type {@code F}, reinterpreting the bytes of this
           * vector without performing any value conversions.
      ...
           * <p>
           * The underlying bits of this vector are copied to the resulting
           * vector without modification, but those bits, before copying,
           * may be truncated if the this vector's bit-size is greater than
           * desired vector's bit size, or filled with zero bits if this
           * vector's bit-size is less than desired vector's bit-size.
      ...
           * <p> The method behaves as if this vector is stored into a byte
           * buffer or array using little-endian byte ordering and then the
           * desired vector is loaded from the same byte buffer or array
           * using the same ordering.
      ```

      ...so it is supposed to be bitwise-exact? In the presence of NaNs, last two paragraphs seem to contradict each other: if we do reinterpretation via buffer load/stores, then implementation-specific behavior for sNaN->qNaN conversion breaks the bit exactness. So, it looks that either a specification should be relaxed to accept these value conversions. Or the implementation should handle vector data as if those are "just" bytes, doing the raw copy?

      This problem surfaces every so often, see for example JDK-8160425.

            psandoz Paul Sandoz
            shade Aleksey Shipilev
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: