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