1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 /** 26 * @test 27 * @bug 8073670 28 * @summary Test that causes C2 to fold two NaNs with different values into a single NaN. 29 * 30 * @run main/othervm -XX:-TieredCompilation -Xcomp 31 * -XX:CompileCommand=compileonly,compiler.c2.FloatingPointFoldingTest::test_double_inf 32 * -XX:CompileCommand=compileonly,compiler.c2.FloatingPointFoldingTest::test_double_zero 33 * -XX:CompileCommand=compileonly,compiler.c2.FloatingPointFoldingTest::test_double_nan 34 * -XX:CompileCommand=compileonly,compiler.c2.FloatingPointFoldingTest::test_float_inf 35 * -XX:CompileCommand=compileonly,compiler.c2.FloatingPointFoldingTest::test_float_zero 36 * -XX:CompileCommand=compileonly,compiler.c2.FloatingPointFoldingTest::test_float_nan 37 * compiler.c2.FloatingPointFoldingTest 38 */ 39 40 package compiler.c2; 41 42 public class FloatingPointFoldingTest { 43 // Double values. 44 public static final long MINUS_INF_LONGBITS = 0xfff0000000000000L; 45 public static final double DOUBLE_MINUS_INF = Double.longBitsToDouble(MINUS_INF_LONGBITS); 46 47 public static final long PLUS_INF_LONGBITS = 0x7ff0000000000000L; 48 public static final double DOUBLE_PLUS_INF = Double.longBitsToDouble(PLUS_INF_LONGBITS); 49 50 public static final long MINUS_ZERO_LONGBITS = 0x8000000000000000L; 51 public static final double DOUBLE_MINUS_ZERO = Double.longBitsToDouble(MINUS_ZERO_LONGBITS); 52 53 // We need two different NaN values. A floating point number is 54 // considered to be NaN is the sign bit is 0, all exponent bits 55 // are set to 1, and at least one bit of the exponent is not zero. 56 // 57 // As java.lang.Double.NaN is 0x7ff8000000000000L, we use 58 // 0x7ffc000000000000L as a second NaN double value. 59 public static final long NAN_LONGBITS = 0x7ffc000000000000L; 60 public static final double DOUBLE_NAN = Double.longBitsToDouble(NAN_LONGBITS); 61 62 // Float values. 63 public static final int MINUS_INF_INTBITS = 0xff800000; 64 public static final float FLOAT_MINUS_INF = Float.intBitsToFloat(MINUS_INF_INTBITS); 65 66 public static final int PLUS_INF_INTBITS = 0x7f800000; 67 public static final float FLOAT_PLUS_INF = Float.intBitsToFloat(PLUS_INF_INTBITS); 68 69 public static final int MINUS_ZERO_INTBITS = 0x80000000; 70 public static final float FLOAT_MINUS_ZERO = Float.intBitsToFloat(MINUS_ZERO_INTBITS); 71 72 // As java.lang.Float.NaN is 0x7fc00000, we use 0x7fe00000 73 // as a second NaN float value. 74 public static final int NAN_INTBITS = 0x7fe00000; 75 public static final float FLOAT_NAN = Float.intBitsToFloat(NAN_INTBITS); 76 77 78 // Double tests. 79 static void test_double_inf(long[] result) { 80 double d1 = DOUBLE_MINUS_INF; 81 double d2 = DOUBLE_PLUS_INF; 82 result[0] = Double.doubleToRawLongBits(d1); 83 result[1] = Double.doubleToRawLongBits(d2); 84 } 85 86 static void test_double_zero(long[] result) { 87 double d1 = DOUBLE_MINUS_ZERO; 88 double d2 = 0; 89 result[0] = Double.doubleToRawLongBits(d1); 90 result[1] = Double.doubleToRawLongBits(d2); 91 } 92 93 static void test_double_nan(long[] result) { 94 double d1 = DOUBLE_NAN; 95 double d2 = Double.NaN; 96 result[0] = Double.doubleToRawLongBits(d1); 97 result[1] = Double.doubleToRawLongBits(d2); 98 } 99 100 // Float tests. 101 static void test_float_inf(int[] result) { 102 float f1 = FLOAT_MINUS_INF; 103 float f2 = FLOAT_PLUS_INF; 104 result[0] = Float.floatToRawIntBits(f1); 105 result[1] = Float.floatToRawIntBits(f2); 106 } 107 108 static void test_float_zero(int[] result) { 109 float f1 = FLOAT_MINUS_ZERO; 110 float f2 = 0; 111 result[0] = Float.floatToRawIntBits(f1); 112 result[1] = Float.floatToRawIntBits(f2); 113 } 114 115 static void test_float_nan(int[] result) { 116 float f1 = FLOAT_NAN; 117 float f2 = Float.NaN; 118 result[0] = Float.floatToRawIntBits(f1); 119 result[1] = Float.floatToRawIntBits(f2); 120 } 121 122 // Check doubles. 123 static void check_double(long[] result, double d1, double d2) { 124 if (result[0] == result[1]) { 125 throw new RuntimeException("ERROR: Two different double values are considered equal. \n" 126 + String.format("\toriginal values: 0x%x 0x%x\n", Double.doubleToRawLongBits(d1), Double.doubleToRawLongBits(d2)) 127 + String.format("\tvalues after execution of method test(): 0x%x 0x%x", result[0], result[1])); 128 } 129 } 130 131 // Check floats. 132 static void check_float(int[] result, float f1, float f2) { 133 if (result[0] == result[1]) { 134 throw new RuntimeException("ERROR: Two different float values are considered equal. \n" 135 + String.format("\toriginal values: 0x%x 0x%x\n", Float.floatToRawIntBits(f1), Float.floatToRawIntBits(f2)) 136 + String.format("\tvalues after execution of method test(): 0x%x 0x%x", result[0], result[1])); 137 } 138 } 139 140 public static void main(String[] args) { 141 // Float tests. 142 143 int[] iresult = new int[2]; 144 145 // -Inf and +Inf. 146 test_float_inf(iresult); 147 check_float(iresult, FLOAT_MINUS_INF, FLOAT_PLUS_INF); 148 149 // 0 and -0. 150 test_float_zero(iresult); 151 check_float(iresult, FLOAT_MINUS_ZERO, 0); 152 153 // Diferrent NaNs. 154 test_float_nan(iresult); 155 check_float(iresult, FLOAT_NAN, Float.NaN); 156 157 // Double tests. 158 159 long[] lresult = new long[2]; 160 161 // -Inf and +Inf. 162 test_double_inf(lresult); 163 check_double(lresult, DOUBLE_MINUS_INF, DOUBLE_PLUS_INF); 164 165 // 0 and -0. 166 test_double_zero(lresult); 167 check_double(lresult, DOUBLE_MINUS_ZERO, 0); 168 169 // Diferrent NaNs. 170 test_double_nan(lresult); 171 check_double(lresult, DOUBLE_NAN, Double.NaN); 172 } 173 }