/* * Copyright (c) 2002, 2018, Oracle and/or its affiliates. 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 * * @summary converted from VM Testbase runtime/jbe/subcommon/subcommon02. * VM Testbase keywords: [runtime] * VM Testbase comments: JDK-7190319 * * @library /vmTestbase * /test/lib * @run driver jdk.test.lib.FileInstaller . . * @run main/othervm vm.compiler.jbe.subcommon.subcommon02.subcommon02 */ package vm.compiler.jbe.subcommon.subcommon02; /* -- Common subexpression elimination testing Using global common subexpression in method fopt() to calculate x**n. */ import java.io.*; public class subcommon02 { int LEN = 5000; int WIDTH = 20; int ngrt10000 = 0; // number of elements > 10,000 int ngrtO10000 = 0; int ngrt1000 = 0; // number of elements > 1,000 int ngrtO1000 = 0; int ngrt100 = 0; // number of elements > 100 int ngrtO100 = 0; int nsmet100 = 0; // number of elements <= 100 int nsmetO100 = 0; double a[][] = new double[LEN][WIDTH]; double aopt[][] = new double[LEN][WIDTH]; public static void main(String args[]) { subcommon02 sce = new subcommon02(); sce.f(); sce.fopt(); if (sce.eCheck()) { System.out.println("Test subcommon02 Passed."); } else { throw new Error("Test subcommon02 Failed."); } } double nPower(int x, int pwr) { return Math.pow(x, pwr); // x**pwr } // non-optimized version void f() { for (int x = 0; x < LEN; x++) { for (int n = 0; n < WIDTH; n++) { if (nPower(x, n) > 10000) { a[x][n] = nPower(x, n); ngrt10000++; } else if (nPower(x, n) > 1000) { a[x][n] = nPower(x, n); ngrt1000++; } else if (nPower(x, n) > 100) { a[x][n] = nPower(x, n); ngrt100++; } else { a[x][n] = nPower(x, n); nsmet100++; } } } } // hand-optimized version void fopt() { for (int x = 0; x < LEN; x++) { for (int n = 0; n < WIDTH; n++) { double tmp = nPower(x, n); aopt[x][n] = tmp; if (tmp > 10000) ngrtO10000++; else if (tmp > 1000) ngrtO1000++; else if (tmp > 100) ngrtO100++; else nsmetO100++; } } } // Compare non-optimized and hand-optimized results boolean eCheck() { boolean r = true; for (int i = 0; i < LEN; i++) { for (int j = 0; j < WIDTH; j++) { // if (a[i][j] != aopt[i][j]) { if (ulpDiff(a[i][j], aopt[i][j]) > 1) { System.out.println("Bad result: a["+i+","+j+"]="+a[i][j]+"; aopt["+i+","+j+"]="+aopt[i][j]); r = false; } } } if ((ngrt10000!=ngrtO10000) || (ngrt1000!=ngrtO1000) || (ngrt100!=ngrtO100) || (nsmetO100!=nsmetO100)) { System.out.println("Bad result: number of elements found is not matching"); r = false; } return r; } /** * Paired-down nextAfter routine */ public static double nextAfter(double base, double direction) { //first check for NaN values if (Double.isNaN(base) || Double.isNaN(direction)) { // return a NaN dervied from the input NaN(s) return base + direction; } else if (base == direction) { return base; } else { long doppelganger; double result=0.0; doppelganger = Double.doubleToLongBits(base + 0.0); if (direction > base) //next greater value { if (doppelganger >= 0 ) result = Double.longBitsToDouble(++doppelganger); else result = Double.longBitsToDouble(--doppelganger); } else if (direction < base) { // calculate next lesser value if (doppelganger > 0) result = Double.longBitsToDouble(--doppelganger); else if (doppelganger < 0) result = Double.longBitsToDouble(++doppelganger); else /* * doppelganger==0L, result is -MIN_VALUE * * The transition from zero (implicitly * positive) to the smallest negative * signed magnitude value must be done * explicitly. */ result = -Double.MIN_VALUE; } return result; } } /* * return ulp of a floating-point value */ static double ulp(double d) { d = Math.abs(d); // don't worry about negative numbers if(Double.isNaN(d)) return Double.NaN; else if(Double.isInfinite(d)) return Double.POSITIVE_INFINITY; else { // can't represent (Double.MAX_VALUE + ulp) so special case it if(d == Double.MAX_VALUE) return 1.9958403095347198E292; // 2^971 else return nextAfter(d, Double.POSITIVE_INFINITY) - d; } } /* * return signed difference in ulps between two floating-point * values. ulpDiff(NaN, NaN) is zero. */ static double ulpDiff(double ref, double test) { double ulp; // assume ref is "correct" value // Infinity, NaN handling if(Double.isInfinite(ref)) { if(ref == test) return 0.0; else return Double.POSITIVE_INFINITY; } else if(Double.isNaN(ref)) { if(Double.isNaN(test)) return 0.0; else return Double.NaN; } else { ulp = ulp(ref); // the expression below can overflow return (test - ref) / ulp; } } }