1 /*
2  * Copyright (c) 2021, Huawei Technologies Co. Ltd. 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 it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 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 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /**
25  * @test
26  * @bug 8263006
27  * @summary Test the result of 8263006's optimization
28  *
29  * @run main/othervm -Xcomp -XX:-TieredCompilation
30  *      compiler.intrinsics.math.MaxMinOptimizeTest
31  */
32 
33 package compiler.intrinsics.math;
34 
35 import java.util.Arrays;
36 
37 public class MaxMinOptimizeTest {
38 
39     private static final float fPos     =  15280.0f;
40     private static final float fNeg     = -55555.5f;
41     private static final float fPosZero =      0.0f;
42     private static final float fNegZero =     -0.0f;
43     private static final float fPosInf  = Float.POSITIVE_INFINITY;
44     private static final float fNegInf  = Float.NEGATIVE_INFINITY;
45     private static final float fNaN     = Float.NaN;
46 
47     private static final float fPosPosAdd = Float.intBitsToFloat(1190051840);
48     private static final float fNegNegAdd = Float.intBitsToFloat(-942079104);
49     private static final float fPosNegAdd = Float.intBitsToFloat(-954379392);
50     private static final float fPosPosMul = Float.intBitsToFloat(1298049424);
51     private static final float fNegNegMul = Float.intBitsToFloat(1329067759);
52     private static final float fPosNegMul = Float.intBitsToFloat(-833985532);
53 
54     private static final double dPos     =  482390926662501720.0;
55     private static final double dNeg     = -333333333333333333.3;
56     private static final double dPosZero =                   0.0;
57     private static final double dNegZero =                  -0.0;
58     private static final double dPosInf  = Double.POSITIVE_INFINITY;
59     private static final double dNegInf  = Double.NEGATIVE_INFINITY;
60     private static final double dNaN     = Double.NaN;
61 
62     private static final double dPosPosAdd = Double.longBitsToDouble(4875928555416607765L);
63     private static final double dNegNegAdd = Double.longBitsToDouble(-4349772506333936299L);
64     private static final double dPosNegAdd = Double.longBitsToDouble(4864042047724301696L);
65     private static final double dPosPosMul = Double.longBitsToDouble(5135907348984537565L);
66     private static final double dNegNegMul = Double.longBitsToDouble(5131119721350321694L);
67     private static final double dPosNegMul = Double.longBitsToDouble(-4089558839395905027L);
68 
69     private static final float[][] f_cases = {
70         //     a         b         min       max        add          mul
71         {     fPos,     fPos,     fPos,     fPos, fPosPosAdd, fPosPosMul},
72         {     fNeg,     fNeg,     fNeg,     fNeg, fNegNegAdd, fNegNegMul},
73         {     fPos,     fNeg,     fNeg,     fPos, fPosNegAdd, fPosNegMul},
74         {     fNeg,     fPos,     fNeg,     fPos, fPosNegAdd, fPosNegMul},
75 
76         { fPosZero, fNegZero, fNegZero, fPosZero,   fPosZero,   fNegZero},
77         { fNegZero, fPosZero, fNegZero, fPosZero,   fPosZero,   fNegZero},
78         { fNegZero, fNegZero, fNegZero, fNegZero,   fNegZero,   fPosZero},
79 
80         {     fPos,  fPosInf,     fPos,  fPosInf,    fPosInf,    fPosInf},
81         {     fNeg,  fNegInf,  fNegInf,     fNeg,    fNegInf,    fPosInf},
82 
83         {     fPos,     fNaN,     fNaN,     fNaN,       fNaN,       fNaN},
84         {     fNaN,     fPos,     fNaN,     fNaN,       fNaN,       fNaN},
85         {     fNeg,     fNaN,     fNaN,     fNaN,       fNaN,       fNaN},
86         {     fNaN,     fNeg,     fNaN,     fNaN,       fNaN,       fNaN},
87 
88         {  fPosInf,     fNaN,     fNaN,     fNaN,       fNaN,       fNaN},
89         {     fNaN,  fPosInf,     fNaN,     fNaN,       fNaN,       fNaN},
90         {  fNegInf,     fNaN,     fNaN,     fNaN,       fNaN,       fNaN},
91         {     fNaN,  fNegInf,     fNaN,     fNaN,       fNaN,       fNaN}
92     };
93 
94     private static final double[][] d_cases = {
95         //     a         b         min       max        add          mul
96         {     dPos,     dPos,     dPos,     dPos, dPosPosAdd, dPosPosMul},
97         {     dNeg,     dNeg,     dNeg,     dNeg, dNegNegAdd, dNegNegMul},
98         {     dPos,     dNeg,     dNeg,     dPos, dPosNegAdd, dPosNegMul},
99         {     dNeg,     dPos,     dNeg,     dPos, dPosNegAdd, dPosNegMul},
100 
101         { dPosZero, dNegZero, dNegZero, dPosZero,   dPosZero,   dNegZero},
102         { dNegZero, dPosZero, dNegZero, dPosZero,   dPosZero,   dNegZero},
103         { dNegZero, dNegZero, dNegZero, dNegZero,   dNegZero,   dPosZero},
104 
105         {     dPos,  dPosInf,     dPos,  dPosInf,    dPosInf,    dPosInf},
106         {     dNeg,  dNegInf,  dNegInf,     dNeg,    dNegInf,    dPosInf},
107 
108         {     dPos,     dNaN,     dNaN,     dNaN,       dNaN,       dNaN},
109         {     dNaN,     dPos,     dNaN,     dNaN,       dNaN,       dNaN},
110         {     dNeg,     dNaN,     dNaN,     dNaN,       dNaN,       dNaN},
111         {     dNaN,     dNeg,     dNaN,     dNaN,       dNaN,       dNaN},
112 
113         {  dPosInf,     dNaN,     dNaN,     dNaN,       dNaN,       dNaN},
114         {     dNaN,  dPosInf,     dNaN,     dNaN,       dNaN,       dNaN},
115         {  dNegInf,     dNaN,     dNaN,     dNaN,       dNaN,       dNaN},
116         {     dNaN,  dNegInf,     dNaN,     dNaN,       dNaN,       dNaN}
117     };
118 
add_opt_float(float a, float b)119     static float add_opt_float(float a, float b) {
120       return Math.max(a, b) + Math.min(a, b);
121     }
122 
mul_opt_float(float a, float b)123     static float mul_opt_float(float a, float b) {
124       return Math.max(a, b) * Math.min(a, b);
125     }
126 
max_opt_float(float a, float b)127     static float max_opt_float(float a, float b) {
128       return Math.max(Math.max(a, b), Math.min(a, b));
129     }
130 
min_opt_float(float a, float b)131     static float min_opt_float(float a, float b) {
132       return Math.min(Math.max(a, b), Math.min(a, b));
133     }
134 
add_opt_double(double a, double b)135     static double add_opt_double(double a, double b) {
136       return Math.max(a, b) + Math.min(a, b);
137     }
138 
mul_opt_double(double a, double b)139     static double mul_opt_double(double a, double b) {
140       return Math.max(a, b) * Math.min(a, b);
141     }
142 
max_opt_double(double a, double b)143     static double max_opt_double(double a, double b) {
144       return Math.max(Math.max(a, b), Math.min(a, b));
145     }
146 
min_opt_double(double a, double b)147     static double min_opt_double(double a, double b) {
148       return Math.min(Math.max(a, b), Math.min(a, b));
149     }
150 
fTest(float[] row)151     private static void fTest(float[] row) {
152         fCheck(row[0], row[1],
153                min_opt_float(row[0], row[1]),
154                max_opt_float(row[0], row[1]),
155                add_opt_float(row[0], row[1]),
156                mul_opt_float(row[0], row[1]),
157                row[2], row[3], row[4], row[5]);
158     }
159 
fCheck(float a, float b, float fmin, float fmax, float fadd, float fmul, float efmin, float efmax, float efadd, float efmul)160     private static void fCheck(float a, float b, float fmin, float fmax, float fadd, float fmul, float efmin, float efmax, float efadd, float efmul) {
161         int min = Float.floatToRawIntBits(fmin);
162         int max = Float.floatToRawIntBits(fmax);
163         int add = Float.floatToRawIntBits(fadd);
164         int mul = Float.floatToRawIntBits(fmul);
165         int emin = Float.floatToRawIntBits(efmin);
166         int emax = Float.floatToRawIntBits(efmax);
167         int eadd = Float.floatToRawIntBits(efadd);
168         int emul = Float.floatToRawIntBits(efmul);
169 
170         if (min != emin || max != emax || add != eadd || mul != emul) {
171             throw new AssertionError("Unexpected result of float test: " +
172                     "a = " + a + ", b = " + b + ", " +
173                     "result = (" + fmin + ", " + fmax + ", " + fadd + ", " + fmul + "), " +
174                     "expected = (" + efmin + ", " + efmax + ", " + efadd + ", " + efmul + ")");
175         }
176     }
177 
dTest(double[] row)178     private static void dTest(double[] row) {
179         dCheck(row[0], row[1],
180                min_opt_double(row[0], row[1]),
181                max_opt_double(row[0], row[1]),
182                add_opt_double(row[0], row[1]),
183                mul_opt_double(row[0], row[1]),
184                row[2], row[3], row[4], row[5]);
185     }
186 
dCheck(double a, double b, double dmin, double dmax, double dadd, double dmul, double edmin, double edmax, double edadd, double edmul)187     private static void dCheck(double a, double b, double dmin, double dmax, double dadd, double dmul, double edmin, double edmax, double edadd, double edmul) {
188         long min = Double.doubleToRawLongBits(dmin);
189         long max = Double.doubleToRawLongBits(dmax);
190         long add = Double.doubleToRawLongBits(dadd);
191         long mul = Double.doubleToRawLongBits(dmul);
192         long emin = Double.doubleToRawLongBits(edmin);
193         long emax = Double.doubleToRawLongBits(edmax);
194         long eadd = Double.doubleToRawLongBits(edadd);
195         long emul = Double.doubleToRawLongBits(edmul);
196 
197         if (min != emin || max != emax || add != eadd || mul != emul) {
198             throw new AssertionError("Unexpected result of double test: " +
199                     "a = " + a + ", b = " + b + ", " +
200                     "result = (" + dmin + ", " + dmax + ", " + dadd + ", " + dmul + "), " +
201                     "expected = (" + edmin + ", " + edmax + ", " + edadd + ", " + edmul + ")");
202         }
203     }
204 
main(String[] args)205     public static void main(String[] args) {
206       Arrays.stream(f_cases).forEach(MaxMinOptimizeTest::fTest);
207       Arrays.stream(d_cases).forEach(MaxMinOptimizeTest::dTest);
208     }
209 }
210