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

sunwjit fails in double calculations when stack is deep

    Details

    • Subcomponent:
      jit
    • CPU:
      generic
    • OS:
      solaris_2.5.1

      Description



      Name: dkC59003 Date: 11/26/98



      JDK 1.2-fcsU / JIT produces incorrect result in some double
      calculation under solaris/sparc and under solaris/x86,
      if the calculation exploits rather deep method's stack.

      Displayed below test program checks double convolution:
          S = A[N-1]*B[N-1] + (... + (A[0]*B[0] + probe) ...)
      intentionally using deep method's stack.

      Vectors A[N],B[N] are generated especially to reveal
      rounding errors, such as fused rounding, or using incorrectly
      extended floating-point format to store intermediate results.
      Similar test programs using the same values for A[N],B[N]
      passes correctly, when calculating in low stack's depth.

      This program uses two ways to trace intermediate sums:
      1) partial sums are stored into C[n] for each n=0,...,N-1,
         when calculating in deep stack, and
      2) expected partial sums E[n] are calculated in low stack depth.

      Here are calculation results:

      -------- Solaris 5.5.1 / UltraSparc-1:

      E[0]=1.1258999068426246E16 C[0]=1.1258999068426246E16
      E[1]=2.0 C[1]=2.0
      E[2]=1.1258999068426246E16 C[2]=1.1258999068426246E16
      E[3]=2.0 C[3]=2.0
      E[4]=1.1258999068426246E16 C[4]=4.0
      E[5]=2.0 C[5]=8.0
      E[6]=1.1258999068426246E16 C[6]=16.0
      E[7]=2.0 C[7]=32.0
      E[8]=1.1258999068426246E16 C[8]=64.0
      E[9]=2.0 C[9]=128.0
      E[10]=1.1258999068426246E16 C[10]=256.0
      E[11]=2.0 C[11]=512.0
      E[12]=1.1258999068426246E16 C[12]=1024.0
      E[13]=2.0 C[13]=2048.0
      E[14]=1.1258999068426246E16 C[14]=4096.0
      E[15]=2.0 C[15]=8192.0
      E[16]=1.1258999068426246E16 C[16]=16384.0
      E[17]=2.0 C[17]=32768.0
      E[18]=1.1258999068426246E16 C[18]=65536.0
      E[19]=2.0 C[19]=131072.0
      E[20]=1.1258999068426246E16 C[20]=262144.0
      E[21]=2.0 C[21]=524288.0

      Convolution failed: double result:
      S = 524288.0 = Double.longBitsToDouble(0x4120000000000000L)
      [ instead of the expected probe = 2.0 ]

      -------- Solaris 5.5.1 / Pentium-II:

      E[0]=1.1258999068426246E16 C[0]=NaN
      E[1]=2.0 C[1]=NaN
      E[2]=1.1258999068426246E16 C[2]=NaN
      E[3]=2.0 C[3]=NaN
      E[4]=1.1258999068426246E16 C[4]=NaN
      E[5]=2.0 C[5]=NaN
      E[6]=1.1258999068426246E16 C[6]=NaN
      E[7]=2.0 C[7]=NaN
      E[8]=1.1258999068426246E16 C[8]=NaN
      E[9]=2.0 C[9]=NaN
      E[10]=1.1258999068426246E16 C[10]=NaN
      E[11]=2.0 C[11]=NaN
      E[12]=1.1258999068426246E16 C[12]=NaN
      E[13]=2.0 C[13]=NaN
      E[14]=1.1258999068426246E16 C[14]=NaN
      E[15]=2.0 C[15]=NaN
      E[16]=1.1258999068426246E16 C[16]=NaN
      E[17]=2.0 C[17]=NaN
      E[18]=1.1258999068426246E16 C[18]=NaN
      E[19]=2.0 C[19]=NaN
      E[20]=1.1258999068426246E16 C[20]=NaN
      E[21]=2.0 C[21]=NaN

      Convolution failed: double result:
      S = NaN = Double.longBitsToDouble(0x7ff8000000000000L)
      [ instead of the expected probe = 2.0 ]

      -------- Windows-NT 4.0 / Pentium-II:

      E[0]=1.1258999068426246E16 C[0]=1.1258999068426246E16
      E[1]=2.0 C[1]=2.0
      E[2]=1.1258999068426246E16 C[2]=1.1258999068426246E16
      E[3]=2.0 C[3]=2.0
      E[4]=1.1258999068426246E16 C[4]=1.1258999068426246E16
      E[5]=2.0 C[5]=2.0
      E[6]=1.1258999068426246E16 C[6]=1.1258999068426246E16
      E[7]=2.0 C[7]=2.0
      E[8]=1.1258999068426246E16 C[8]=1.1258999068426246E16
      E[9]=2.0 C[9]=2.0
      E[10]=1.1258999068426246E16 C[10]=1.1258999068426246E16
      E[11]=2.0 C[11]=2.0
      E[12]=1.1258999068426246E16 C[12]=1.1258999068426246E16
      E[13]=2.0 C[13]=2.0
      E[14]=1.1258999068426246E16 C[14]=1.1258999068426246E16
      E[15]=2.0 C[15]=2.0
      E[16]=1.1258999068426246E16 C[16]=1.1258999068426246E16
      E[17]=2.0 C[17]=2.0
      E[18]=1.1258999068426246E16 C[18]=1.1258999068426246E16
      E[19]=2.0 C[19]=2.0
      E[20]=1.1258999068426246E16 C[20]=1.1258999068426246E16
      E[21]=2.0 C[21]=2.0

      --------

      Both solaris/sparc and solaris/x86 results are obviously incorrect
      (and pentium/win32 results are correctly equal to the expeccted).

      Errors only arise (under solaris sparc or x86) when JIT is on;
      there is no error when JIT is off.

      The problem seems to appear in JDK 1.2beta;
      earlier JDK 1.0.2, and 1.1.x pass the test.

      This bug is revealed by JCK-1.2b tests:
      vm/fp/fpm035/fpm03503m2/fpm03503m2.html
      vm/fp/fpm035/fpm03503m4/fpm03503m4.html
      vm/fp/fpm035/fpm03503m6/fpm03503m6.html

      Full sources of the test program consist of the following two files:

      -------- fpm03503m2a_bug.jasm:

      /* Ident: @(#)fpm03503m2a.jasm generated from: @(#)fpm03503m.jmpp 1.1 98/11/12 */
      /* Copyright 25.11.98 Sun Microsystems, Inc. All Rights Reserved */

      // package javasoft/sqe/tests/vm/fp/fpm035/fpm03503m2;

      super class fpm03503m2a_bug
      {

      static final Field N:I = int 22;

      Method "<init>":"()V"
      stack 1 locals 1
      {
      aload_0;
      invokespecial Method java/lang/Object."<init>":"()V";
      return;
      }

      //
      // static double convolution (double probe, double A[], double B[]) {
      // double S = probe;
      // for (int n=0; n<N; n++)
      // S += A[n]*B[n];
      // return S;
      // };
      //
      static strict Method convolution:"(D[D[D[D)D"
      stack 92 locals 7
      {
      aload_3;
      sipush 21;
      daload; // stack <-- A[21]
      aload_2;
      sipush 21;
      daload; // stack <-- B[21]

      aload_3;
      sipush 20;
      daload; // stack <-- A[20]
      aload_2;
      sipush 20;
      daload; // stack <-- B[20]

      aload_3;
      sipush 19;
      daload; // stack <-- A[19]
      aload_2;
      sipush 19;
      daload; // stack <-- B[19]

      aload_3;
      sipush 18;
      daload; // stack <-- A[18]
      aload_2;
      sipush 18;
      daload; // stack <-- B[18]

      aload_3;
      sipush 17;
      daload; // stack <-- A[17]
      aload_2;
      sipush 17;
      daload; // stack <-- B[17]

      aload_3;
      sipush 16;
      daload; // stack <-- A[16]
      aload_2;
      sipush 16;
      daload; // stack <-- B[16]

      aload_3;
      sipush 15;
      daload; // stack <-- A[15]
      aload_2;
      sipush 15;
      daload; // stack <-- B[15]

      aload_3;
      sipush 14;
      daload; // stack <-- A[14]
      aload_2;
      sipush 14;
      daload; // stack <-- B[14]

      aload_3;
      sipush 13;
      daload; // stack <-- A[13]
      aload_2;
      sipush 13;
      daload; // stack <-- B[13]

      aload_3;
      sipush 12;
      daload; // stack <-- A[12]
      aload_2;
      sipush 12;
      daload; // stack <-- B[12]

      aload_3;
      sipush 11;
      daload; // stack <-- A[11]
      aload_2;
      sipush 11;
      daload; // stack <-- B[11]

      aload_3;
      sipush 10;
      daload; // stack <-- A[10]
      aload_2;
      sipush 10;
      daload; // stack <-- B[10]

      aload_3;
      sipush 9;
      daload; // stack <-- A[9]
      aload_2;
      sipush 9;
      daload; // stack <-- B[9]

      aload_3;
      sipush 8;
      daload; // stack <-- A[8]
      aload_2;
      sipush 8;
      daload; // stack <-- B[8]

      aload_3;
      sipush 7;
      daload; // stack <-- A[7]
      aload_2;
      sipush 7;
      daload; // stack <-- B[7]

      aload_3;
      sipush 6;
      daload; // stack <-- A[6]
      aload_2;
      sipush 6;
      daload; // stack <-- B[6]

      aload_3;
      sipush 5;
      daload; // stack <-- A[5]
      aload_2;
      sipush 5;
      daload; // stack <-- B[5]

      aload_3;
      sipush 4;
      daload; // stack <-- A[4]
      aload_2;
      sipush 4;
      daload; // stack <-- B[4]

      aload_3;
      sipush 3;
      daload; // stack <-- A[3]
      aload_2;
      sipush 3;
      daload; // stack <-- B[3]

      aload_3;
      sipush 2;
      daload; // stack <-- A[2]
      aload_2;
      sipush 2;
      daload; // stack <-- B[2]

      aload_3;
      sipush 1;
      daload; // stack <-- A[1]
      aload_2;
      sipush 1;
      daload; // stack <-- B[1]

      aload_3;
      sipush 0;
      daload; // stack <-- A[0]
      aload_2;
      sipush 0;
      daload; // stack <-- B[0]

      dload_0; // S:=probe, and let S be on stack's top

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[0]*B[0]

      dup2;
      dstore 5;
      aload 4;
      sipush 0;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[1]*B[1]

      dup2;
      dstore 5;
      aload 4;
      sipush 1;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[2]*B[2]

      dup2;
      dstore 5;
      aload 4;
      sipush 2;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[3]*B[3]

      dup2;
      dstore 5;
      aload 4;
      sipush 3;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[4]*B[4]

      dup2;
      dstore 5;
      aload 4;
      sipush 4;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[5]*B[5]

      dup2;
      dstore 5;
      aload 4;
      sipush 5;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[6]*B[6]

      dup2;
      dstore 5;
      aload 4;
      sipush 6;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[7]*B[7]

      dup2;
      dstore 5;
      aload 4;
      sipush 7;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[8]*B[8]

      dup2;
      dstore 5;
      aload 4;
      sipush 8;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[9]*B[9]

      dup2;
      dstore 5;
      aload 4;
      sipush 9;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[10]*B[10]

      dup2;
      dstore 5;
      aload 4;
      sipush 10;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[11]*B[11]

      dup2;
      dstore 5;
      aload 4;
      sipush 11;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[12]*B[12]

      dup2;
      dstore 5;
      aload 4;
      sipush 12;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[13]*B[13]

      dup2;
      dstore 5;
      aload 4;
      sipush 13;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[14]*B[14]

      dup2;
      dstore 5;
      aload 4;
      sipush 14;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[15]*B[15]

      dup2;
      dstore 5;
      aload 4;
      sipush 15;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[16]*B[16]

      dup2;
      dstore 5;
      aload 4;
      sipush 16;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[17]*B[17]

      dup2;
      dstore 5;
      aload 4;
      sipush 17;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[18]*B[18]

      dup2;
      dstore 5;
      aload 4;
      sipush 18;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[19]*B[19]

      dup2;
      dstore 5;
      aload 4;
      sipush 19;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[20]*B[20]

      dup2;
      dstore 5;
      aload 4;
      sipush 20;
      dload 5;
      dastore;

      dup2_x2;
      pop2;
      dstore 5;
      dup2_x2;
      pop2;
      dload 5;
      dmul;
      dadd; // S += A[21]*B[21]

      dup2;
      dstore 5;
      aload 4;
      sipush 21;
      dload 5;
      dastore;

      dreturn;
      }

      } // end class fpm03503m2a

      -------- fpm03503m2_bug.java:

      /* Ident: @(#)fpm03503m2.java generated from: @(#)fpm03503m.jmpp 1.1 98/11/12 */
      /* Copyright 25.11.98 Sun Microsystems, Inc. All Rights Reserved */

      // package javasoft.sqe.tests.vm.fp.fpm035.fpm03503m2;

      import java.io.PrintStream;
        
      public class fpm03503m2_bug {

          public static void main (String args[]) {
              System.exit(run(args, System.out) + 95/*STATUS_TEMP*/);
          };


          public static int run (String args[], PrintStream out) {
      final int N = 22; // it is essential, that N is even and N/2 is odd
      double A[] = new double [ N ];
      double B[] = new double [ N ];
      double C[] = new double [ N ];

      for (int n=0; n<N; n++)
      if (n%2 == 0) {
      A[n] = (double) 0x8000000000001L;
      B[n] = (double) 0x5L;
      } else {
      A[n] = (double) 0xa000000000001L;
      B[n] = - (double) 0x4L;
      };

      final double probe = 2;

      double S = fpm03503m2a_bug.convolution(probe,A,B,C);

      out.println("");
      double E=probe;
      for (int n=0; n<N; n++) {
      E += A[n]*B[n];
      out.println("E["+n+"]="+E + "\tC["+n+"]="+C[n]);
      };

      if (S == probe)
      return 0/*STATUS_PASSED*/;

      out.println("\nConvolution failed: double result:");
      out.println("S = " + S + " = " +
      "Double.longBitsToDouble(0x" +
      Long.toHexString(Double.doubleToLongBits(S)) + "L)");
      out.println("[ instead of the expected probe = " + probe + " ]");
      if (S == probe+N/2)
      out.println("double mantissa is probably wider than standard.");
      else if (S == 2*probe)
      out.println("rounding of intermediate results is probably ommited.");
      out.println("");

            return 2/*STATUS_FAILED*/;
          };

      }

      --------

      ======================================================================

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              dkhukhrosunw Dmitry Khukhro (Inactive)
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Imported:
                Indexed: