Path: blob/master/test/hotspot/jtreg/compiler/intrinsics/math/TestFpMinMaxIntrinsics.java
41153 views
/*1* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2018, 2019, Arm Limited. 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 it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 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 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*/2324/*25* @test26* @bug 821204327* @summary Test compiler intrinsics of floating-point Math.min/max28* @library /test/lib29*30* @comment the test isn't marked by 'randomness' b/c randomSearchTree case isn't used31* @run main/othervm -Xint compiler.intrinsics.math.TestFpMinMaxIntrinsics sanityTests 132* @run main/othervm -XX:+UnlockDiagnosticVMOptions33* -Xcomp -XX:TieredStopAtLevel=134* -XX:CompileOnly=java/lang/Math35* compiler.intrinsics.math.TestFpMinMaxIntrinsics sanityTests 136* @run main/othervm -XX:+UnlockDiagnosticVMOptions37* -Xcomp -XX:-TieredCompilation38* -XX:CompileOnly=java/lang/Math39* compiler.intrinsics.math.TestFpMinMaxIntrinsics sanityTests 140* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions41* -XX:-TieredCompilation -XX:CompileThresholdScaling=0.142* -XX:CompileCommand=print,compiler/intrinsics/math/TestFpMinMaxIntrinsics.*Test*43* compiler.intrinsics.math.TestFpMinMaxIntrinsics sanityTests 1000044* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions45* -XX:-TieredCompilation -Xcomp46* -XX:CompileCommand=print,compiler/intrinsics/math/TestFpMinMaxIntrinsics.*Test*47* -XX:CompileCommand=compileonly,compiler/intrinsics/math/TestFpMinMaxIntrinsics.*Test*48* compiler.intrinsics.math.TestFpMinMaxIntrinsics reductionTests 10049*/5051package compiler.intrinsics.math;5253import java.util.Arrays;54import java.util.Random;55import java.lang.reflect.Method;56import jdk.test.lib.Utils;5758public class TestFpMinMaxIntrinsics {5960private static final float fPos = 15280.0f;61private static final float fNeg = -55555.5f;62private static final float fPosZero = 0.0f;63private static final float fNegZero = -0.0f;64private static final float fPosInf = Float.POSITIVE_INFINITY;65private static final float fNegInf = Float.NEGATIVE_INFINITY;66private static final float fNaN = Float.NaN;6768private static final double dPos = 482390926662501720.0;69private static final double dNeg = -333333333333333333.3;70private static final double dPosZero = 0.0;71private static final double dNegZero = -0.0;72private static final double dPosInf = Double.POSITIVE_INFINITY;73private static final double dNegInf = Double.NEGATIVE_INFINITY;74private static final double dNaN = Double.NaN;7576private static final float[][] f_cases = {77// a b min max78{ fPos, fPos, fPos, fPos },79{ fNeg, fNeg, fNeg, fNeg },80{ fPos, fNeg, fNeg, fPos },81{ fNeg, fPos, fNeg, fPos },8283{ fPosZero, fNegZero, fNegZero, fPosZero },84{ fNegZero, fPosZero, fNegZero, fPosZero },85{ fNegZero, fNegZero, fNegZero, fNegZero },8687{ fPos, fPosInf, fPos, fPosInf },88{ fNeg, fNegInf, fNegInf, fNeg },8990{ fPos, fNaN, fNaN, fNaN },91{ fNaN, fPos, fNaN, fNaN },92{ fNeg, fNaN, fNaN, fNaN },93{ fNaN, fNeg, fNaN, fNaN },9495{ fPosInf, fNaN, fNaN, fNaN },96{ fNaN, fPosInf, fNaN, fNaN },97{ fNegInf, fNaN, fNaN, fNaN },98{ fNaN, fNegInf, fNaN, fNaN }99};100101private static final double[][] d_cases = {102// a b min max103{ dPos, dPos, dPos, dPos },104{ dNeg, dNeg, dNeg, dNeg },105{ dPos, dNeg, dNeg, dPos },106{ dNeg, dPos, dNeg, dPos },107108{ dPosZero, dNegZero, dNegZero, dPosZero },109{ dNegZero, dPosZero, dNegZero, dPosZero },110{ dNegZero, dNegZero, dNegZero, dNegZero },111112{ dPos, dPosInf, dPos, dPosInf },113{ dNeg, dNegInf, dNegInf, dNeg },114115{ dPos, dNaN, dNaN, dNaN },116{ dNaN, dPos, dNaN, dNaN },117{ dNeg, dNaN, dNaN, dNaN },118{ dNaN, dNeg, dNaN, dNaN },119120{ dPosInf, dNaN, dNaN, dNaN },121{ dNaN, dPosInf, dNaN, dNaN },122{ dNegInf, dNaN, dNaN, dNaN },123{ dNaN, dNegInf, dNaN, dNaN }124};125126private static void fTest(float[] row) {127fCheck(row[0], row[1], Math.min(row[0], row[1]), Math.max(row[0], row[1]), row[2], row[3]);128}129130private static void fReductionTest(float[] row) {131float fmin = row[0], fmax = row[0];132133for (int i=0; i<100; i++) {134fmin = Math.min(fmin, row[1]);135fmax = Math.max(fmax, row[1]);136}137138fCheck(row[0], row[1], fmin, fmax, row[2], row[3]);139}140141private static void fCheck(float a, float b, float fmin, float fmax, float efmin, float efmax) {142int min = Float.floatToRawIntBits(fmin);143int max = Float.floatToRawIntBits(fmax);144int emin = Float.floatToRawIntBits(efmin);145int emax = Float.floatToRawIntBits(efmax);146147if (min != emin || max != emax) {148throw new AssertionError("Unexpected result of float min/max: " +149"a = " + a + ", b = " + b + ", " +150"result = (" + fmin + ", " + fmax + "), " +151"expected = (" + efmin + ", " + efmax + ")");152}153}154155private static void dTest(double[] row) {156dCheck(row[0], row[1], Math.min(row[0], row[1]), Math.max(row[0], row[1]), row[2], row[3]);157}158159private static void dReductionTest(double[] row) {160double dmin = row[0], dmax = row[0];161162for (int i=0; i<100; i++) {163dmin = Math.min(dmin, row[1]);164dmax = Math.max(dmax, row[1]);165}166167dCheck(row[0], row[1], dmin, dmax, row[2], row[3]);168}169170private static void dCheck(double a, double b, double dmin, double dmax, double edmin, double edmax) {171double min = Double.doubleToRawLongBits(dmin);172double max = Double.doubleToRawLongBits(dmax);173double emin = Double.doubleToRawLongBits(edmin);174double emax = Double.doubleToRawLongBits(edmax);175176if (min != emin || max != emax) {177throw new AssertionError("Unexpected result of double min/max: " +178"a = " + a + ", b = " + b + ", " +179"result = (" + dmin + ", " + dmax + "), " +180"expected = (" + edmin + ", " + edmax + ")");181}182}183184public static void sanityTests() {185Arrays.stream(f_cases).forEach(TestFpMinMaxIntrinsics::fTest);186Arrays.stream(d_cases).forEach(TestFpMinMaxIntrinsics::dTest);187}188189public static void reductionTests() {190Arrays.stream(f_cases).forEach(TestFpMinMaxIntrinsics::fReductionTest);191Arrays.stream(d_cases).forEach(TestFpMinMaxIntrinsics::dReductionTest);192}193194public static void main(String[] args) throws Exception {195Method m = TestFpMinMaxIntrinsics.class.getDeclaredMethod(args[0]);196for (int i = 0 ; i < Integer.parseInt(args[1]) ; i++)197m.invoke(null);198}199200private static final int COUNT = 1000;201private static final int LOOPS = 100;202203private static Random r = Utils.getRandomInstance();204205private static Node[] pool = new Node[COUNT];206207private static long time = 0;208private static long times = 0;209210public static void init() {211for (int i=0; i<COUNT; i++)212pool[i] = new Node(Double.NaN);213}214215public static void finish() {216// String sorted = pool[0].toString();217// System.out.println("Sorted: {" + sorted.substring(0, Math.min(sorted.length(), 180)) + "... }");218System.out.println("Average time: " + (time/times) + " ns");219}220221public static void randomSearchTree() {222init();223for (int l=0; l < LOOPS; l++) {224Node root = pool[0].reset(r.nextDouble());225226for (int i=1; i<COUNT; i++)227insert(root, pool[i].reset(r.nextDouble()));228}229finish();230}231232public static void sortedSearchTree() {233init();234for (int l=0; l < LOOPS; l++) {235Node root = pool[0].reset(-0.0);236237for (int i=1; i<COUNT; i++)238insert(root, pool[i].reset(i-1));239}240finish();241}242243private static class Node {244private double value;245private Node min;246private Node max;247248public Node(double d) { value = d; }249250public Node reset(double d) { value = d; min = max = null; return this; }251252@Override253public String toString() {254return (min != null ? min + ", " : "") +255value +256(max != null ? ", " + max : "");257}258}259260private static Node insert(Node root, Node d) {261for ( ; ; ) {262long rootBits = Double.doubleToRawLongBits(root.value);263long dBits = Double.doubleToRawLongBits(d.value);264265// No duplicates266if (rootBits == dBits)267return root;268269long delta = System.nanoTime();270271double dmin = min(root.value, d.value);272273time += System.nanoTime() - delta;274times++;275276long minBits = Double.doubleToRawLongBits(dmin);277278if (minBits == dBits)279if (root.min != null)280root = root.min;281else282return root.min = d;283else284if (root.max != null)285root = root.max;286else287return root.max = d;288}289}290291// Wrapper method to prevent code reordering from affecting measures (JLS 17.4).292private static double min(double a, double b) {293return Math.min(a, b);294}295}296297298