Thu, 19 Mar 2015 19:53:34 +0100
8074869: C2 code generator can replace -0.0f with +0.0f on Linux
Summary: Instead of 'fpclass', use cast float->int and double->long to check if value is +0.0f and +0.0d, respectively.
Reviewed-by: kvn, simonis, dlong
1.1 --- a/src/cpu/ppc/vm/ppc.ad Wed Mar 18 18:12:01 2015 -0700 1.2 +++ b/src/cpu/ppc/vm/ppc.ad Thu Mar 19 19:53:34 2015 +0100 1.3 @@ -4418,11 +4418,11 @@ 1.4 interface(CONST_INTER); 1.5 %} 1.6 1.7 -// constant 'float +0.0'. 1.8 +// Float Immediate: +0.0f. 1.9 operand immF_0() %{ 1.10 - predicate((n->getf() == 0) && 1.11 - (fpclassify(n->getf()) == FP_ZERO) && (signbit(n->getf()) == 0)); 1.12 + predicate(jint_cast(n->getf()) == 0); 1.13 match(ConF); 1.14 + 1.15 op_cost(0); 1.16 format %{ %} 1.17 interface(CONST_INTER);
2.1 --- a/src/cpu/sparc/vm/sparc.ad Wed Mar 18 18:12:01 2015 -0700 2.2 +++ b/src/cpu/sparc/vm/sparc.ad Thu Mar 19 19:53:34 2015 +0100 2.3 @@ -3760,13 +3760,9 @@ 2.4 interface(CONST_INTER); 2.5 %} 2.6 2.7 +// Double Immediate: +0.0d 2.8 operand immD0() %{ 2.9 -#ifdef _LP64 2.10 - // on 64-bit architectures this comparision is faster 2.11 predicate(jlong_cast(n->getd()) == 0); 2.12 -#else 2.13 - predicate((n->getd() == 0) && (fpclass(n->getd()) == FP_PZERO)); 2.14 -#endif 2.15 match(ConD); 2.16 2.17 op_cost(0); 2.18 @@ -3783,9 +3779,9 @@ 2.19 interface(CONST_INTER); 2.20 %} 2.21 2.22 -// Float Immediate: 0 2.23 -operand immF0() %{ 2.24 - predicate((n->getf() == 0) && (fpclass(n->getf()) == FP_PZERO)); 2.25 +// Float Immediate: +0.0f 2.26 +operand immF0() %{ 2.27 + predicate(jint_cast(n->getf()) == 0); 2.28 match(ConF); 2.29 2.30 op_cost(0);
3.1 --- a/src/share/vm/utilities/globalDefinitions_gcc.hpp Wed Mar 18 18:12:01 2015 -0700 3.2 +++ b/src/share/vm/utilities/globalDefinitions_gcc.hpp Thu Mar 19 19:53:34 2015 +0100 3.3 @@ -44,14 +44,6 @@ 3.4 #endif // SOLARIS 3.5 3.6 #include <math.h> 3.7 -#ifndef FP_PZERO 3.8 -// Linux doesn't have positive/negative zero 3.9 -#define FP_PZERO FP_ZERO 3.10 -#endif 3.11 -#if (!defined fpclass) && ((!defined SPARC) || (!defined SOLARIS)) 3.12 -#define fpclass fpclassify 3.13 -#endif 3.14 - 3.15 #include <time.h> 3.16 #include <fcntl.h> 3.17 #include <dlfcn.h>
4.1 --- a/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp Wed Mar 18 18:12:01 2015 -0700 4.2 +++ b/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp Thu Mar 19 19:53:34 2015 +0100 4.3 @@ -48,15 +48,6 @@ 4.4 # include <ieeefp.h> 4.5 #endif 4.6 # include <math.h> 4.7 -#ifdef LINUX 4.8 -#ifndef FP_PZERO 4.9 - // Linux doesn't have positive/negative zero 4.10 - #define FP_PZERO FP_ZERO 4.11 -#endif 4.12 -#ifndef fpclass 4.13 - #define fpclass fpclassify 4.14 -#endif 4.15 -#endif 4.16 # include <time.h> 4.17 # include <fcntl.h> 4.18 # include <dlfcn.h>
5.1 --- a/src/share/vm/utilities/globalDefinitions_xlc.hpp Wed Mar 18 18:12:01 2015 -0700 5.2 +++ b/src/share/vm/utilities/globalDefinitions_xlc.hpp Thu Mar 19 19:53:34 2015 +0100 5.3 @@ -41,14 +41,6 @@ 5.4 #include <wchar.h> 5.5 5.6 #include <math.h> 5.7 -#ifndef FP_PZERO 5.8 -// Linux doesn't have positive/negative zero 5.9 -#define FP_PZERO FP_ZERO 5.10 -#endif 5.11 -#if (!defined fpclass) 5.12 -#define fpclass fpclassify 5.13 -#endif 5.14 - 5.15 #include <time.h> 5.16 #include <fcntl.h> 5.17 #include <dlfcn.h>
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/compiler/loopopts/ConstFPVectorization.java Thu Mar 19 19:53:34 2015 +0100 6.3 @@ -0,0 +1,63 @@ 6.4 +/* 6.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. 6.11 + * 6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.15 + * version 2 for more details (a copy is included in the LICENSE file that 6.16 + * accompanied this code). 6.17 + * 6.18 + * You should have received a copy of the GNU General Public License version 6.19 + * 2 along with this work; if not, write to the Free Software Foundation, 6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.21 + * 6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.23 + * or visit www.oracle.com if you need additional information or have any 6.24 + * questions. 6.25 + * 6.26 + */ 6.27 + 6.28 +/** 6.29 + * @test 6.30 + * @bug 8074869 6.31 + * @summary C2 code generator can replace -0.0f with +0.0f on Linux 6.32 + * @run main ConstFPVectorization 8 6.33 + * @author volker.simonis@gmail.com 6.34 + * 6.35 + */ 6.36 + 6.37 +public class ConstFPVectorization { 6.38 + 6.39 + static float[] f = new float[16]; 6.40 + static double[] d = new double[16]; 6.41 + 6.42 + static void floatLoop(int count) { 6.43 + for (int i = 0; i < count; i++) { 6.44 + f[i] = -0.0f; 6.45 + } 6.46 + } 6.47 + 6.48 + static void doubleLoop(int count) { 6.49 + for (int i = 0; i < count; i++) { 6.50 + d[i] = -0.0d; 6.51 + } 6.52 + } 6.53 + 6.54 + public static void main(String args[]) { 6.55 + for (int i = 0; i < 10_000; i++) { 6.56 + floatLoop(Integer.parseInt(args[0])); 6.57 + doubleLoop(Integer.parseInt(args[0])); 6.58 + } 6.59 + for (int i = 0; i < Integer.parseInt(args[0]); i++) { 6.60 + if (Float.floatToRawIntBits(f[i]) != Float.floatToRawIntBits(-0.0f)) 6.61 + throw new Error("Float error at index " + i); 6.62 + if (Double.doubleToRawLongBits(d[i]) != Double.doubleToRawLongBits(-0.0d)) 6.63 + throw new Error("Double error at index " + i); 6.64 + } 6.65 + } 6.66 +}