JDK-4971850 : fpl03602m3 fails on Ultra III
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: sparc
  • Submitted: 2003-12-22
  • Updated: 2004-01-28
  • Resolved: 2004-01-28
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0 b36Fixed
Related Reports
Relates :  
Description
The JCK test fpl03602m3 will fail on a Ultra III given a chance to properly compile the core of the test case.

The program below will show this failure more easily than running w/runThese.

// Trimmed version of test fpl03602m3
//
// Fails on UltraSparc III because c2 generates different long to float code there.
//
// Best observed with "-server -Xbatch -XX:+PrintCompilation -XX:CompileOnly=.do_test -XX:-Inline"

public class test {

  float correct_value = 0.0f;
  static float correct_values[] = new float[64];

    public static void main (String args[]) {
      for (int i = 0; i < correct_values.length; i++) {
        correct_values[i] = 0.0f;
      }
      // Run enough times to trigger compilation
      for (int i = 0; i < 20000; i++) {
        if (0 != run()) {
          System.out.println("Fails on teration " + i);
          System.exit(96);
        }
      }
    };


    public static int run () {
	return (new test()).reallyRun();
    };

  boolean print_failure(int width, float test_value, long tricky_bits) {
    // Save the correct values the first time through, i.e., when we interpret.
    if (correct_values[width] == 0.0) {
      correct_values[width] = test_value;
    }
    // Compare against the "correct" value on each iteration.
    if (test_value != correct_values[width]) {
      System.out.println("");
      System.out.println("test failed");
      System.out.println("width=" + width);
      System.out.println("test_value: " + test_value + " " + Integer.toHexString(Float.floatToIntBits(test_value)));
      System.out.println("instead of: " + correct_values[width] + " " + Integer.toHexString(Float.floatToIntBits(correct_values[width])));
      System.out.println("tricky_bits: " + Long.toHexString(tricky_bits));
      System.out.println("");

      return false;
    }

    return true;
  }

  float do_test(float width_shift, float diff_shift, long tricky_bits) {
    float test_value = (float)tricky_bits;
    // test_value /= diff_shift;
    // test_value /= width_shift;

    return test_value;
  }

     int reallyRun () {
	boolean OK = true;
	int format_std_width = 24; // single-standard mantissa width
	int format_min_width = 32; // shortest single-extended mantissa
	int format_max_width = 62; // need 63-bit positive long to check format 62

	// If actual float format has mantissa wider than format_max_width 
	// bits, this test does not checks correctness of the implementstion.

	correct_value = Float.intBitsToFloat(0x3f800001); // 1+epsilon

	for (int format_width=format_min_width; 
		 format_width<=format_max_width;
		 format_width++) {

          int diff = format_width - format_std_width;
          long tricky_bits = (((1L << format_std_width) + 1) << diff) + 1;

          float test_value = do_test((float) (1L << format_std_width), (float) (1L<<diff), tricky_bits);

          OK = print_failure(format_width, test_value, tricky_bits);
	};

        return (OK? 0/*STATUS_PASSED*/: 2/*STATUS_FAILED*/);
    };

}

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger-beta2 FIXED IN: tiger-beta2 INTEGRATED IN: tiger-b36 tiger-beta2
14-06-2004

EVALUATION Background: USII has instructions that can quickly convert from long to float and long to double. Unfortunetly USIII has a very limited subset of that (+-2^51). Anything outside of that range is very slow (2700cycles vs 4cycles). That's why we can not use these fast instructions on USIII. Bug Fixed: The slow (USIII version) of L2F was broken. It originally converted L2D and then D2F. This double conversion resulted in lost precision in the last ulp. The easy fix would have been to use fxtos, but that was unacceptable in terms of performance. The other way was to call out to sharedRuntime::l2f, and is implemented here. ###@###.### 2004-01-14
14-01-2004

SUGGESTED FIX The problem appears to be in the convL2F_reg_slow_fxtof instruction sequence, which is only used on US-III boxes. The sequence is used to avoid performance issues on US-III with fxtos, and would fail on any Sparc platform using that used it. The proper solution may be to go back to calling l2f() instead of attempting inline code. ###@###.### 2003-12-22
22-12-2003