/* * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2019, Arm Limited. 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. */ /* * @test * @bug 8212043 * @summary Test compiler intrinsics of floating-point Math.min/max * * @run main/othervm -Xint compiler.intrinsics.math.TestFpMinMaxIntrinsics sanityTests 1 * @run main/othervm -XX:+UnlockDiagnosticVMOptions * -Xcomp -XX:TieredStopAtLevel=1 * -XX:CompileOnly=java/lang/Math * compiler.intrinsics.math.TestFpMinMaxIntrinsics sanityTests 1 * @run main/othervm -XX:+UnlockDiagnosticVMOptions * -Xcomp -XX:-TieredCompilation * -XX:CompileOnly=java/lang/Math * compiler.intrinsics.math.TestFpMinMaxIntrinsics sanityTests 1 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions * -XX:-TieredCompilation -XX:CompileThresholdScaling=0.1 * -XX:CompileCommand=print,compiler/intrinsics/math/TestFpMinMaxIntrinsics.*Test* * compiler.intrinsics.math.TestFpMinMaxIntrinsics sanityTests 10000 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions * -XX:-TieredCompilation -Xcomp * -XX:CompileCommand=print,compiler/intrinsics/math/TestFpMinMaxIntrinsics.*Test* * -XX:CompileCommand=compileonly,compiler/intrinsics/math/TestFpMinMaxIntrinsics.*Test* * compiler.intrinsics.math.TestFpMinMaxIntrinsics reductionTests 100 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions * -XX:+TieredCompilation * -XX:CompileCommand=print,compiler/intrinsics/math/TestFpMinMaxIntrinsics.min* * -XX:CompileCommand=dontinline,compiler/intrinsics/math/TestFpMinMaxIntrinsics.min* * compiler.intrinsics.math.TestFpMinMaxIntrinsics randomSearchTree 1 * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions * -XX:+TieredCompilation * -XX:CompileCommand=print,compiler/intrinsics/math/TestFpMinMaxIntrinsics.min* * -XX:CompileCommand=dontinline,compiler/intrinsics/math/TestFpMinMaxIntrinsics.min* * compiler.intrinsics.math.TestFpMinMaxIntrinsics sortedSearchTree 1 */ package compiler.intrinsics.math; import java.util.Arrays; import java.util.Random; import java.lang.reflect.Method; public class TestFpMinMaxIntrinsics { private static final float fPos = 15280.0f; private static final float fNeg = -55555.5f; private static final float fPosZero = 0.0f; private static final float fNegZero = -0.0f; private static final float fPosInf = Float.POSITIVE_INFINITY; private static final float fNegInf = Float.NEGATIVE_INFINITY; private static final float fNaN = Float.NaN; private static final double dPos = 482390926662501720.0; private static final double dNeg = -333333333333333333.3; private static final double dPosZero = 0.0; private static final double dNegZero = -0.0; private static final double dPosInf = Double.POSITIVE_INFINITY; private static final double dNegInf = Double.NEGATIVE_INFINITY; private static final double dNaN = Double.NaN; private static final float[][] f_cases = { // a b min max { fPos, fPos, fPos, fPos }, { fNeg, fNeg, fNeg, fNeg }, { fPos, fNeg, fNeg, fPos }, { fNeg, fPos, fNeg, fPos }, { fPosZero, fNegZero, fNegZero, fPosZero }, { fNegZero, fPosZero, fNegZero, fPosZero }, { fNegZero, fNegZero, fNegZero, fNegZero }, { fPos, fPosInf, fPos, fPosInf }, { fNeg, fNegInf, fNegInf, fNeg }, { fPos, fNaN, fNaN, fNaN }, { fNaN, fPos, fNaN, fNaN }, { fNeg, fNaN, fNaN, fNaN }, { fNaN, fNeg, fNaN, fNaN }, { fPosInf, fNaN, fNaN, fNaN }, { fNaN, fPosInf, fNaN, fNaN }, { fNegInf, fNaN, fNaN, fNaN }, { fNaN, fNegInf, fNaN, fNaN } }; private static final double[][] d_cases = { // a b min max { dPos, dPos, dPos, dPos }, { dNeg, dNeg, dNeg, dNeg }, { dPos, dNeg, dNeg, dPos }, { dNeg, dPos, dNeg, dPos }, { dPosZero, dNegZero, dNegZero, dPosZero }, { dNegZero, dPosZero, dNegZero, dPosZero }, { dNegZero, dNegZero, dNegZero, dNegZero }, { dPos, dPosInf, dPos, dPosInf }, { dNeg, dNegInf, dNegInf, dNeg }, { dPos, dNaN, dNaN, dNaN }, { dNaN, dPos, dNaN, dNaN }, { dNeg, dNaN, dNaN, dNaN }, { dNaN, dNeg, dNaN, dNaN }, { dPosInf, dNaN, dNaN, dNaN }, { dNaN, dPosInf, dNaN, dNaN }, { dNegInf, dNaN, dNaN, dNaN }, { dNaN, dNegInf, dNaN, dNaN } }; private static void fTest(float[] row) { fCheck(row[0], row[1], Math.min(row[0], row[1]), Math.max(row[0], row[1]), row[2], row[3]); } private static void fReductionTest(float[] row) { float fmin = row[0], fmax = row[0]; for (int i=0; i<100; i++) { fmin = Math.min(fmin, row[1]); fmax = Math.max(fmax, row[1]); } fCheck(row[0], row[1], fmin, fmax, row[2], row[3]); } private static void fCheck(float a, float b, float fmin, float fmax, float efmin, float efmax) { int min = Float.floatToRawIntBits(fmin); int max = Float.floatToRawIntBits(fmax); int emin = Float.floatToRawIntBits(efmin); int emax = Float.floatToRawIntBits(efmax); if (min != emin || max != emax) { throw new AssertionError("Unexpected result of float min/max: " + "a = " + a + ", b = " + b + ", " + "result = (" + fmin + ", " + fmax + "), " + "expected = (" + efmin + ", " + efmax + ")"); } } private static void dTest(double[] row) { dCheck(row[0], row[1], Math.min(row[0], row[1]), Math.max(row[0], row[1]), row[2], row[3]); } private static void dReductionTest(double[] row) { double dmin = row[0], dmax = row[0]; for (int i=0; i<100; i++) { dmin = Math.min(dmin, row[1]); dmax = Math.max(dmax, row[1]); } dCheck(row[0], row[1], dmin, dmax, row[2], row[3]); } private static void dCheck(double a, double b, double dmin, double dmax, double edmin, double edmax) { double min = Double.doubleToRawLongBits(dmin); double max = Double.doubleToRawLongBits(dmax); double emin = Double.doubleToRawLongBits(edmin); double emax = Double.doubleToRawLongBits(edmax); if (min != emin || max != emax) { throw new AssertionError("Unexpected result of double min/max: " + "a = " + a + ", b = " + b + ", " + "result = (" + dmin + ", " + dmax + "), " + "expected = (" + edmin + ", " + edmax + ")"); } } public static void sanityTests() { Arrays.stream(f_cases).forEach(TestFpMinMaxIntrinsics::fTest); Arrays.stream(d_cases).forEach(TestFpMinMaxIntrinsics::dTest); } public static void reductionTests() { Arrays.stream(f_cases).forEach(TestFpMinMaxIntrinsics::fReductionTest); Arrays.stream(d_cases).forEach(TestFpMinMaxIntrinsics::dReductionTest); } public static void main(String[] args) throws Exception { Method m = TestFpMinMaxIntrinsics.class.getDeclaredMethod(args[0]); for (int i = 0 ; i < Integer.parseInt(args[1]) ; i++) m.invoke(null); } private static final int COUNT = 1000; private static final int LOOPS = 100; private static Random r = new Random(); private static Node[] pool = new Node[COUNT]; private static long time = 0; private static long times = 0; public static void init() { for (int i=0; i