mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8345219: C2: x86_64 should not go to interpreter stubs for NaNs handling
Reviewed-by: epeter, kvn
This commit is contained in:
parent
16ef6e2a18
commit
f3b4350e0f
5 changed files with 355 additions and 2 deletions
|
@ -1448,7 +1448,7 @@ nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
|
||||||
// do the compilation
|
// do the compilation
|
||||||
if (method->is_native()) {
|
if (method->is_native()) {
|
||||||
if (!PreferInterpreterNativeStubs || method->is_method_handle_intrinsic()) {
|
if (!PreferInterpreterNativeStubs || method->is_method_handle_intrinsic()) {
|
||||||
#if defined(X86) && !defined(ZERO)
|
#if defined(IA32) && !defined(ZERO)
|
||||||
// The following native methods:
|
// The following native methods:
|
||||||
//
|
//
|
||||||
// java.lang.Float.intBitsToFloat
|
// java.lang.Float.intBitsToFloat
|
||||||
|
@ -1470,7 +1470,7 @@ nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
|
||||||
method->intrinsic_id() == vmIntrinsics::_doubleToRawLongBits))) {
|
method->intrinsic_id() == vmIntrinsics::_doubleToRawLongBits))) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
#endif // X86 && !ZERO
|
#endif // IA32 && !ZERO
|
||||||
|
|
||||||
// To properly handle the appendix argument for out-of-line calls we are using a small trampoline that
|
// To properly handle the appendix argument for out-of-line calls we are using a small trampoline that
|
||||||
// pops off the appendix argument and jumps to the target (see gen_special_dispatch in SharedRuntime).
|
// pops off the appendix argument and jumps to the target (see gen_special_dispatch in SharedRuntime).
|
||||||
|
|
127
test/hotspot/jtreg/compiler/c2/irTests/TestFPConversion.java
Normal file
127
test/hotspot/jtreg/compiler/c2/irTests/TestFPConversion.java
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
package compiler.c2.irTests;
|
||||||
|
|
||||||
|
import compiler.lib.ir_framework.*;
|
||||||
|
import jdk.test.lib.Asserts;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 8345219
|
||||||
|
* @summary Test that code generation for FP conversion works as intended
|
||||||
|
* @library /test/lib /
|
||||||
|
* @requires os.arch != "x86" & os.arch != "i386"
|
||||||
|
* @run driver compiler.c2.irTests.TestFPConversion
|
||||||
|
*/
|
||||||
|
public class TestFPConversion {
|
||||||
|
static final double[] DOUBLES = new double[] {
|
||||||
|
Double.NEGATIVE_INFINITY,
|
||||||
|
-Double.MAX_VALUE,
|
||||||
|
-1.0,
|
||||||
|
-Double.MIN_VALUE,
|
||||||
|
-0.0,
|
||||||
|
0.0,
|
||||||
|
Double.MIN_VALUE,
|
||||||
|
1.0,
|
||||||
|
Double.MAX_VALUE,
|
||||||
|
Double.POSITIVE_INFINITY,
|
||||||
|
Double.NaN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static final float[] FLOATS = new float[] {
|
||||||
|
Float.NEGATIVE_INFINITY,
|
||||||
|
-Float.MAX_VALUE,
|
||||||
|
-1.0F,
|
||||||
|
-Float.MIN_VALUE,
|
||||||
|
-0.0F,
|
||||||
|
0.0F,
|
||||||
|
Float.MIN_VALUE,
|
||||||
|
1.0F,
|
||||||
|
Float.MAX_VALUE,
|
||||||
|
Float.POSITIVE_INFINITY,
|
||||||
|
Float.NaN,
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
TestFramework.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@IR(counts = {IRNode.MOV_D2L, "1"})
|
||||||
|
public long doubleToRawLongBits(double x) {
|
||||||
|
return Double.doubleToRawLongBits(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@IR(counts = {IRNode.MOV_D2L, "1"})
|
||||||
|
public long doubleToLongBits(double x) {
|
||||||
|
return Double.doubleToLongBits(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@IR(counts = {IRNode.MOV_L2D, "1"})
|
||||||
|
public double longBitsToDouble(long x) {
|
||||||
|
return Double.longBitsToDouble(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@IR(counts = {IRNode.MOV_F2I, "1"})
|
||||||
|
public int floatToRawIntBits(float x) {
|
||||||
|
return Float.floatToRawIntBits(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@IR(counts = {IRNode.MOV_F2I, "1"})
|
||||||
|
public int floatToIntBits(float x) {
|
||||||
|
return Float.floatToIntBits(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@IR(counts = {IRNode.MOV_I2F, "1"})
|
||||||
|
public float intBitsToFloat(int x) {
|
||||||
|
return Float.intBitsToFloat(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Run(test = {"doubleToRawLongBits", "doubleToLongBits", "longBitsToDouble",
|
||||||
|
"floatToRawIntBits", "floatToIntBits", "intBitsToFloat"})
|
||||||
|
public void runTests() {
|
||||||
|
for (int i = 0; i < DOUBLES.length; i++) {
|
||||||
|
double d = DOUBLES[i];
|
||||||
|
long l1 = doubleToRawLongBits(d);
|
||||||
|
long l2 = doubleToLongBits(d);
|
||||||
|
double d1 = longBitsToDouble(l1);
|
||||||
|
double d2 = longBitsToDouble(l2);
|
||||||
|
Asserts.assertEquals(d, d1);
|
||||||
|
Asserts.assertEquals(d, d2);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < FLOATS.length; i++) {
|
||||||
|
float f = FLOATS[i];
|
||||||
|
int i1 = floatToRawIntBits(f);
|
||||||
|
int i2 = floatToIntBits(f);
|
||||||
|
float f1 = intBitsToFloat(i1);
|
||||||
|
float f2 = intBitsToFloat(i2);
|
||||||
|
Asserts.assertEquals(f, f1);
|
||||||
|
Asserts.assertEquals(f, f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1169,6 +1169,26 @@ public class IRNode {
|
||||||
beforeMatchingNameRegex(MOD_L, "ModL");
|
beforeMatchingNameRegex(MOD_L, "ModL");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final String MOV_F2I = PREFIX + "MOV_F2I" + POSTFIX;
|
||||||
|
static {
|
||||||
|
beforeMatchingNameRegex(MOV_F2I, "MoveF2I");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String MOV_I2F = PREFIX + "MOV_I2F" + POSTFIX;
|
||||||
|
static {
|
||||||
|
beforeMatchingNameRegex(MOV_I2F, "MoveI2F");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String MOV_D2L = PREFIX + "MOV_D2L" + POSTFIX;
|
||||||
|
static {
|
||||||
|
beforeMatchingNameRegex(MOV_D2L, "MoveD2L");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String MOV_L2D = PREFIX + "MOD_L2D" + POSTFIX;
|
||||||
|
static {
|
||||||
|
beforeMatchingNameRegex(MOV_L2D, "MoveL2D");
|
||||||
|
}
|
||||||
|
|
||||||
public static final String MUL = PREFIX + "MUL" + POSTFIX;
|
public static final String MUL = PREFIX + "MUL" + POSTFIX;
|
||||||
static {
|
static {
|
||||||
beforeMatchingNameRegex(MUL, "Mul(I|L|F|D)");
|
beforeMatchingNameRegex(MUL, "Mul(I|L|F|D)");
|
||||||
|
|
103
test/micro/org/openjdk/bench/java/lang/DoubleBitConversion.java
Normal file
103
test/micro/org/openjdk/bench/java/lang/DoubleBitConversion.java
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
package org.openjdk.bench.java.lang;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Fork;
|
||||||
|
import org.openjdk.jmh.annotations.Measurement;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.Setup;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
import org.openjdk.jmh.annotations.Warmup;
|
||||||
|
import org.openjdk.jmh.infra.Blackhole;
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@State(Scope.Thread)
|
||||||
|
@Warmup(iterations = 3, time = 1)
|
||||||
|
@Measurement(iterations = 3, time = 1)
|
||||||
|
@Fork(3)
|
||||||
|
public class DoubleBitConversion {
|
||||||
|
|
||||||
|
double doubleZero = 0;
|
||||||
|
double doubleOne = 1;
|
||||||
|
double doubleNan = Double.NaN;
|
||||||
|
|
||||||
|
long longDoubleZero = Double.doubleToLongBits(0);
|
||||||
|
long longDoubleOne = Double.doubleToLongBits(1);
|
||||||
|
long longDoubleNaN = Double.doubleToLongBits(Double.NaN);
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long doubleToRawLongBits_zero() {
|
||||||
|
return Double.doubleToRawLongBits(doubleZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long doubleToRawLongBits_one() {
|
||||||
|
return Double.doubleToRawLongBits(doubleOne);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long doubleToRawLongBits_NaN() {
|
||||||
|
return Double.doubleToRawLongBits(doubleNan);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long doubleToLongBits_zero() {
|
||||||
|
return Double.doubleToLongBits(doubleZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long doubleToLongBits_one() {
|
||||||
|
return Double.doubleToLongBits(doubleOne);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public long doubleToLongBits_NaN() {
|
||||||
|
return Double.doubleToLongBits(doubleNan);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double longBitsToDouble_zero() {
|
||||||
|
return Double.longBitsToDouble(longDoubleZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double longBitsToDouble_one() {
|
||||||
|
return Double.longBitsToDouble(longDoubleOne);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public double longBitsToDouble_NaN() {
|
||||||
|
return Double.longBitsToDouble(longDoubleNaN);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
103
test/micro/org/openjdk/bench/java/lang/FloatBitConversion.java
Normal file
103
test/micro/org/openjdk/bench/java/lang/FloatBitConversion.java
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
package org.openjdk.bench.java.lang;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.Benchmark;
|
||||||
|
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||||
|
import org.openjdk.jmh.annotations.Fork;
|
||||||
|
import org.openjdk.jmh.annotations.Measurement;
|
||||||
|
import org.openjdk.jmh.annotations.Mode;
|
||||||
|
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||||
|
import org.openjdk.jmh.annotations.Scope;
|
||||||
|
import org.openjdk.jmh.annotations.Setup;
|
||||||
|
import org.openjdk.jmh.annotations.State;
|
||||||
|
import org.openjdk.jmh.annotations.Warmup;
|
||||||
|
import org.openjdk.jmh.infra.Blackhole;
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@State(Scope.Thread)
|
||||||
|
@Warmup(iterations = 3, time = 1)
|
||||||
|
@Measurement(iterations = 3, time = 1)
|
||||||
|
@Fork(3)
|
||||||
|
public class FloatBitConversion {
|
||||||
|
|
||||||
|
float floatZero = 0;
|
||||||
|
float floatOne = 1;
|
||||||
|
float floatNan = Float.NaN;
|
||||||
|
|
||||||
|
int intFloatZero = Float.floatToIntBits(0);
|
||||||
|
int intFloatOne = Float.floatToIntBits(1);
|
||||||
|
int intFloatNaN = Float.floatToIntBits(Float.NaN);
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int floatToRawIntBits_zero() {
|
||||||
|
return Float.floatToRawIntBits(floatZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int floatToRawIntBits_one() {
|
||||||
|
return Float.floatToRawIntBits(floatOne);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int floatToRawIntBits_NaN() {
|
||||||
|
return Float.floatToRawIntBits(floatNan);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int floatToIntBits_zero() {
|
||||||
|
return Float.floatToIntBits(floatZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int floatToIntBits_one() {
|
||||||
|
return Float.floatToIntBits(floatOne);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public int floatToIntBits_NaN() {
|
||||||
|
return Float.floatToIntBits(floatNan);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float intBitsToFloat_zero() {
|
||||||
|
return Float.intBitsToFloat(intFloatZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float intBitsToFloat_one() {
|
||||||
|
return Float.intBitsToFloat(intFloatOne);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public float intBitsToFloat_NaN() {
|
||||||
|
return Float.intBitsToFloat(intFloatNaN);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue