1 /* 2 * Copyright (c) 2002, 2020, Oracle and/or its affiliates. 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 * 27 * @summary converted from VM Testbase runtime/jbe/subcommon/subcommon02. 28 * VM Testbase keywords: [runtime] 29 * VM Testbase comments: 7190319 30 * 31 * @library /vmTestbase 32 * /test/lib 33 * @run main/othervm vm.compiler.jbe.subcommon.subcommon02.subcommon02 34 */ 35 36 package vm.compiler.jbe.subcommon.subcommon02; 37 38 /* -- Common subexpression elimination testing 39 Using global common subexpression in method fopt() to calculate x**n. 40 */ 41 import java.io.*; 42 43 public class subcommon02 { 44 int LEN = 5000; 45 int WIDTH = 20; 46 int ngrt10000 = 0; // number of elements > 10,000 47 int ngrtO10000 = 0; 48 int ngrt1000 = 0; // number of elements > 1,000 49 int ngrtO1000 = 0; 50 int ngrt100 = 0; // number of elements > 100 51 int ngrtO100 = 0; 52 int nsmet100 = 0; // number of elements <= 100 53 int nsmetO100 = 0; 54 double a[][] = new double[LEN][WIDTH]; 55 double aopt[][] = new double[LEN][WIDTH]; 56 main(String args[])57 public static void main(String args[]) { 58 subcommon02 sce = new subcommon02(); 59 60 sce.f(); 61 sce.fopt(); 62 if (sce.eCheck()) { 63 System.out.println("Test subcommon02 Passed."); 64 } else { 65 throw new Error("Test subcommon02 Failed."); 66 } 67 } 68 69 nPower(int x, int pwr)70 double nPower(int x, int pwr) { 71 return Math.pow(x, pwr); // x**pwr 72 } 73 74 // non-optimized version f()75 void f() { 76 for (int x = 0; x < LEN; x++) { 77 for (int n = 0; n < WIDTH; n++) { 78 if (nPower(x, n) > 10000) { 79 a[x][n] = nPower(x, n); 80 ngrt10000++; 81 } 82 else if (nPower(x, n) > 1000) { 83 a[x][n] = nPower(x, n); 84 ngrt1000++; 85 } 86 else if (nPower(x, n) > 100) { 87 a[x][n] = nPower(x, n); 88 ngrt100++; 89 } 90 else { 91 a[x][n] = nPower(x, n); 92 nsmet100++; 93 } 94 } 95 } 96 } 97 98 // hand-optimized version fopt()99 void fopt() { 100 for (int x = 0; x < LEN; x++) { 101 for (int n = 0; n < WIDTH; n++) { 102 double tmp = nPower(x, n); 103 104 aopt[x][n] = tmp; 105 if (tmp > 10000) 106 ngrtO10000++; 107 else if (tmp > 1000) 108 ngrtO1000++; 109 else if (tmp > 100) 110 ngrtO100++; 111 else 112 nsmetO100++; 113 } 114 } 115 } 116 117 // Compare non-optimized and hand-optimized results eCheck()118 boolean eCheck() { 119 boolean r = true; 120 121 for (int i = 0; i < LEN; i++) { 122 for (int j = 0; j < WIDTH; j++) { 123 // if (a[i][j] != aopt[i][j]) { 124 if (ulpDiff(a[i][j], aopt[i][j]) > 1) { 125 System.out.println("Bad result: a["+i+","+j+"]="+a[i][j]+"; aopt["+i+","+j+"]="+aopt[i][j]); 126 r = false; 127 } 128 } 129 } 130 131 if ((ngrt10000!=ngrtO10000) || (ngrt1000!=ngrtO1000) || (ngrt100!=ngrtO100) || (nsmetO100!=nsmetO100)) { 132 System.out.println("Bad result: number of elements found is not matching"); 133 r = false; 134 } 135 return r; 136 } 137 138 /** 139 * Paired-down nextAfter routine 140 */ nextAfter(double base, double direction)141 public static double nextAfter(double base, double direction) { 142 //first check for NaN values 143 if (Double.isNaN(base) || Double.isNaN(direction)) { 144 // return a NaN dervied from the input NaN(s) 145 return base + direction; 146 } else if (base == direction) { 147 return base; 148 } else { 149 long doppelganger; 150 double result=0.0; 151 152 doppelganger = Double.doubleToLongBits(base + 0.0); 153 if (direction > base) //next greater value 154 { 155 if (doppelganger >= 0 ) 156 result = Double.longBitsToDouble(++doppelganger); 157 else 158 result = Double.longBitsToDouble(--doppelganger); 159 } else if (direction < base) { // calculate next lesser value 160 if (doppelganger > 0) 161 result = Double.longBitsToDouble(--doppelganger); 162 else if (doppelganger < 0) 163 result = Double.longBitsToDouble(++doppelganger); 164 else 165 /* 166 * doppelganger==0L, result is -MIN_VALUE 167 * 168 * The transition from zero (implicitly 169 * positive) to the smallest negative 170 * signed magnitude value must be done 171 * explicitly. 172 */ 173 result = -Double.MIN_VALUE; 174 } 175 176 return result; 177 } 178 } 179 180 /* 181 * return ulp of a floating-point value 182 */ ulp(double d)183 static double ulp(double d) { 184 d = Math.abs(d); // don't worry about negative numbers 185 186 if(Double.isNaN(d)) 187 return Double.NaN; 188 else if(Double.isInfinite(d)) 189 return Double.POSITIVE_INFINITY; 190 else { 191 // can't represent (Double.MAX_VALUE + ulp) so special case it 192 if(d == Double.MAX_VALUE) 193 return 1.9958403095347198E292; // 2^971 194 else 195 return nextAfter(d, Double.POSITIVE_INFINITY) - d; 196 } 197 } 198 199 200 /* 201 * return signed difference in ulps between two floating-point 202 * values. ulpDiff(NaN, NaN) is zero. 203 */ ulpDiff(double ref, double test)204 static double ulpDiff(double ref, double test) { 205 double ulp; 206 // assume ref is "correct" value 207 208 // Infinity, NaN handling 209 if(Double.isInfinite(ref)) { 210 if(ref == test) 211 return 0.0; 212 else 213 return Double.POSITIVE_INFINITY; 214 } else if(Double.isNaN(ref)) { 215 if(Double.isNaN(test)) 216 return 0.0; 217 else 218 return Double.NaN; 219 } 220 else { 221 ulp = ulp(ref); 222 // the expression below can overflow 223 return (test - ref) / ulp; 224 } 225 } 226 227 } 228