/* * Copyright (c) 2021, Huawei Technologies Co., Ltd. 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 8263006 * @summary Test the result of 8263006's optimization * * @run main/othervm -Xcomp -XX:-TieredCompilation * compiler.intrinsics.math.MaxMinOptimizeTest */ package compiler.intrinsics.math; import java.util.Arrays; public class MaxMinOptimizeTest { 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 float fPosPosAdd = Float.intBitsToFloat(1190051840); private static final float fNegNegAdd = Float.intBitsToFloat(-942079104); private static final float fPosNegAdd = Float.intBitsToFloat(-954379392); private static final float fPosPosMul = Float.intBitsToFloat(1298049424); private static final float fNegNegMul = Float.intBitsToFloat(1329067759); private static final float fPosNegMul = Float.intBitsToFloat(-833985532); 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 double dPosPosAdd = Double.longBitsToDouble(4875928555416607765L); private static final double dNegNegAdd = Double.longBitsToDouble(-4349772506333936299L); private static final double dPosNegAdd = Double.longBitsToDouble(4864042047724301696L); private static final double dPosPosMul = Double.longBitsToDouble(5135907348984537565L); private static final double dNegNegMul = Double.longBitsToDouble(5131119721350321694L); private static final double dPosNegMul = Double.longBitsToDouble(-4089558839395905027L); private static final float[][] f_cases = { // a b min max add mul { fPos, fPos, fPos, fPos, fPosPosAdd, fPosPosMul}, { fNeg, fNeg, fNeg, fNeg, fNegNegAdd, fNegNegMul}, { fPos, fNeg, fNeg, fPos, fPosNegAdd, fPosNegMul}, { fNeg, fPos, fNeg, fPos, fPosNegAdd, fPosNegMul}, { fPosZero, fNegZero, fNegZero, fPosZero, fPosZero, fNegZero}, { fNegZero, fPosZero, fNegZero, fPosZero, fPosZero, fNegZero}, { fNegZero, fNegZero, fNegZero, fNegZero, fNegZero, fPosZero}, { fPos, fPosInf, fPos, fPosInf, fPosInf, fPosInf}, { fNeg, fNegInf, fNegInf, fNeg, fNegInf, fPosInf}, { fPos, fNaN, fNaN, fNaN, fNaN, fNaN}, { fNaN, fPos, fNaN, fNaN, fNaN, fNaN}, { fNeg, fNaN, fNaN, fNaN, fNaN, fNaN}, { fNaN, fNeg, fNaN, fNaN, fNaN, fNaN}, { fPosInf, fNaN, fNaN, fNaN, fNaN, fNaN}, { fNaN, fPosInf, fNaN, fNaN, fNaN, fNaN}, { fNegInf, fNaN, fNaN, fNaN, fNaN, fNaN}, { fNaN, fNegInf, fNaN, fNaN, fNaN, fNaN} }; private static final double[][] d_cases = { // a b min max add mul { dPos, dPos, dPos, dPos, dPosPosAdd, dPosPosMul}, { dNeg, dNeg, dNeg, dNeg, dNegNegAdd, dNegNegMul}, { dPos, dNeg, dNeg, dPos, dPosNegAdd, dPosNegMul}, { dNeg, dPos, dNeg, dPos, dPosNegAdd, dPosNegMul}, { dPosZero, dNegZero, dNegZero, dPosZero, dPosZero, dNegZero}, { dNegZero, dPosZero, dNegZero, dPosZero, dPosZero, dNegZero}, { dNegZero, dNegZero, dNegZero, dNegZero, dNegZero, dPosZero}, { dPos, dPosInf, dPos, dPosInf, dPosInf, dPosInf}, { dNeg, dNegInf, dNegInf, dNeg, dNegInf, dPosInf}, { dPos, dNaN, dNaN, dNaN, dNaN, dNaN}, { dNaN, dPos, dNaN, dNaN, dNaN, dNaN}, { dNeg, dNaN, dNaN, dNaN, dNaN, dNaN}, { dNaN, dNeg, dNaN, dNaN, dNaN, dNaN}, { dPosInf, dNaN, dNaN, dNaN, dNaN, dNaN}, { dNaN, dPosInf, dNaN, dNaN, dNaN, dNaN}, { dNegInf, dNaN, dNaN, dNaN, dNaN, dNaN}, { dNaN, dNegInf, dNaN, dNaN, dNaN, dNaN} }; static float add_opt_float(float a, float b) { return Math.max(a, b) + Math.min(a, b); } static float mul_opt_float(float a, float b) { return Math.max(a, b) * Math.min(a, b); } static float max_opt_float(float a, float b) { return Math.max(Math.max(a, b), Math.min(a, b)); } static float min_opt_float(float a, float b) { return Math.min(Math.max(a, b), Math.min(a, b)); } static double add_opt_double(double a, double b) { return Math.max(a, b) + Math.min(a, b); } static double mul_opt_double(double a, double b) { return Math.max(a, b) * Math.min(a, b); } static double max_opt_double(double a, double b) { return Math.max(Math.max(a, b), Math.min(a, b)); } static double min_opt_double(double a, double b) { return Math.min(Math.max(a, b), Math.min(a, b)); } private static void fTest(float[] row) { fCheck(row[0], row[1], min_opt_float(row[0], row[1]), max_opt_float(row[0], row[1]), add_opt_float(row[0], row[1]), mul_opt_float(row[0], row[1]), row[2], row[3], row[4], row[5]); } private static void fCheck(float a, float b, float fmin, float fmax, float fadd, float fmul, float efmin, float efmax, float efadd, float efmul) { int min = Float.floatToRawIntBits(fmin); int max = Float.floatToRawIntBits(fmax); int add = Float.floatToRawIntBits(fadd); int mul = Float.floatToRawIntBits(fmul); int emin = Float.floatToRawIntBits(efmin); int emax = Float.floatToRawIntBits(efmax); int eadd = Float.floatToRawIntBits(efadd); int emul = Float.floatToRawIntBits(efmul); if (min != emin || max != emax || add != eadd || mul != emul) { throw new AssertionError("Unexpected result of float test: " + "a = " + a + ", b = " + b + ", " + "result = (" + fmin + ", " + fmax + ", " + fadd + ", " + fmul + "), " + "expected = (" + efmin + ", " + efmax + ", " + efadd + ", " + efmul + ")"); } } private static void dTest(double[] row) { dCheck(row[0], row[1], min_opt_double(row[0], row[1]), max_opt_double(row[0], row[1]), add_opt_double(row[0], row[1]), mul_opt_double(row[0], row[1]), row[2], row[3], row[4], row[5]); } private static void dCheck(double a, double b, double dmin, double dmax, double dadd, double dmul, double edmin, double edmax, double edadd, double edmul) { long min = Double.doubleToRawLongBits(dmin); long max = Double.doubleToRawLongBits(dmax); long add = Double.doubleToRawLongBits(dadd); long mul = Double.doubleToRawLongBits(dmul); long emin = Double.doubleToRawLongBits(edmin); long emax = Double.doubleToRawLongBits(edmax); long eadd = Double.doubleToRawLongBits(edadd); long emul = Double.doubleToRawLongBits(edmul); if (min != emin || max != emax || add != eadd || mul != emul) { throw new AssertionError("Unexpected result of double test: " + "a = " + a + ", b = " + b + ", " + "result = (" + dmin + ", " + dmax + ", " + dadd + ", " + dmul + "), " + "expected = (" + edmin + ", " + edmax + ", " + edadd + ", " + edmul + ")"); } } public static void main(String[] args) { Arrays.stream(f_cases).forEach(MaxMinOptimizeTest::fTest); Arrays.stream(d_cases).forEach(MaxMinOptimizeTest::dTest); } }