test/compiler/intrinsics/mathexact/Verify.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff test/compiler/intrinsics/mathexact

test/compiler/intrinsics/mathexact/Verify.java

Print this page
rev 5462 : 8026844: Various Math functions needs intrinsification
Reviewed-by: duke


   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 public class Verify {
  25   public static String throwWord(boolean threw) {
  26     return (threw ? "threw" : "didn't throw");
  27   }
  28 
  29   public static void verify(int a, int b) {





































  30     boolean exception1 = false, exception2 = false;
  31     int result1 = 0, result2 = 0;
  32     try {
  33       result1 = testIntrinsic(a, b);
  34     } catch (ArithmeticException e) {
  35       exception1 = true;
  36     }
  37     try {
  38       result2 = testNonIntrinsic(a, b);
  39     } catch (ArithmeticException e) {
  40       exception2 = true;
  41     }
  42 
  43     if (exception1 != exception2) {
  44       throw new RuntimeException("Intrinsic version " + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b);
  45     }
  46     if (result1 != result2) {
  47       throw new RuntimeException("Intrinsic version returned: " + a + " while NonIntrinsic version returned: " + b);



























































  48     }
  49   }
  50 
  51   public static int testIntrinsic(int a, int b) {
  52     return java.lang.Math.addExact(a, b);



















































































































  53   }
  54 
  55   public static int testNonIntrinsic(int a, int b) {
  56     return safeAddExact(a, b);



  57   }
  58 
  59   // Copied java.lang.Math.addExact to avoid intrinsification
  60   public static int safeAddExact(int x, int y) {


























































  61     int r = x + y;
  62     // HD 2-12 Overflow iff both arguments have the opposite sign of the result
  63     if (((x ^ r) & (y ^ r)) < 0) {
  64       throw new ArithmeticException("integer overflow");
  65     }
  66     return r;

  67   }

































































































































































































































































































































  68 }


   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 public class Verify {
  25     public static String throwWord(boolean threw) {
  26         return (threw ? "threw" : "didn't throw");
  27     }
  28 
  29     public static void verifyResult(UnaryMethod method, int result1, int result2, boolean exception1, boolean exception2, int value) {
  30         if (exception1 != exception2) {
  31             throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version" + throwWord(exception2) + " for: " + value);
  32         }
  33         if (result1 != result2) {
  34             throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);
  35         }
  36     }
  37 
  38     public static void verifyResult(UnaryLongMethod method, long result1, long result2, boolean exception1, boolean exception2, long value) {
  39         if (exception1 != exception2) {
  40             throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version" + throwWord(exception2) + " for: " + value);
  41         }
  42         if (result1 != result2) {
  43             throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);
  44         }
  45     }
  46 
  47     private static void verifyResult(BinaryMethod method, int result1, int result2, boolean exception1, boolean exception2, int a, int b) {
  48         if (exception1 != exception2) {
  49             throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b);
  50         }
  51         if (result1 != result2) {
  52             throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);
  53         }
  54     }
  55 
  56     private static void verifyResult(BinaryLongMethod method, long result1, long result2, boolean exception1, boolean exception2, long a, long b) {
  57         if (exception1 != exception2) {
  58             throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b);
  59         }
  60         if (result1 != result2) {
  61             throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2);
  62         }
  63     }
  64 
  65 
  66     public static void verifyUnary(int a, UnaryMethod method) {
  67         boolean exception1 = false, exception2 = false;
  68         int result1 = 0, result2 = 0;
  69         try {
  70             result1 = method.checkMethod(a);
  71         } catch (ArithmeticException e) {
  72             exception1 = true;
  73         }
  74         try {
  75             result2 = method.safeMethod(a);
  76         } catch (ArithmeticException e) {
  77             exception2 = true;
  78         }
  79 
  80         verifyResult(method, result1, result2, exception1, exception2, a);

  81     }
  82 
  83     public static void verifyUnary(long a, UnaryLongMethod method) {
  84         boolean exception1 = false, exception2 = false;
  85         long result1 = 0, result2 = 0;
  86         try {
  87             result1 = method.checkMethod(a);
  88         } catch (ArithmeticException e) {
  89             exception1 = true;
  90         }
  91         try {
  92             result2 = method.safeMethod(a);
  93         } catch (ArithmeticException e) {
  94             exception2 = true;
  95         }
  96 
  97         verifyResult(method, result1, result2, exception1, exception2, a);
  98     }
  99 
 100 
 101     public static void verifyBinary(int a, int b, BinaryMethod method) {
 102         boolean exception1 = false, exception2 = false;
 103         int result1 = 0, result2 = 0;
 104         try {
 105             result1 = method.checkMethod(a, b);
 106         } catch (ArithmeticException e) {
 107             exception1 = true;
 108         }
 109         try {
 110             result2 = method.safeMethod(a, b);
 111         } catch (ArithmeticException e) {
 112             exception2 = true;
 113         }
 114 
 115         verifyResult(method, result1, result2, exception1, exception2, a, b);
 116     }
 117 
 118     public static void verifyBinary(long a, long b, BinaryLongMethod method) {
 119         boolean exception1 = false, exception2 = false;
 120         long result1 = 0, result2 = 0;
 121         try {
 122             result1 = method.checkMethod(a, b);
 123         } catch (ArithmeticException e) {
 124             exception1 = true;
 125         }
 126         try {
 127             result2 = method.safeMethod(a, b);
 128         } catch (ArithmeticException e) {
 129             exception2 = true;
 130         }
 131 
 132         verifyResult(method, result1, result2, exception1, exception2, a, b);
 133     }
 134 
 135 
 136     public static class LoadTest {
 137         public static java.util.Random rnd = new java.util.Random();
 138         public static int[] values = new int[256];
 139 
 140         public static void init() {
 141             for (int i = 0; i < values.length; ++i) {
 142                 values[i] = rnd.nextInt();
 143             }
 144         }
 145 
 146         public static void verify(BinaryMethod method) {
 147             for (int i = 0; i < 50000; ++i) {
 148                 Verify.verifyBinary(values[i & 255], values[i & 255] - i, method);
 149                 Verify.verifyBinary(values[i & 255] + i, values[i & 255] - i, method);
 150                 Verify.verifyBinary(values[i & 255], values[i & 255], method);
 151                 if ((i & 1) == 1 && i > 5) {
 152                     Verify.verifyBinary(values[i & 255] + i, values[i & 255] - i, method);
 153                 } else {
 154                     Verify.verifyBinary(values[i & 255] - i, values[i & 255] + i, method);
 155                 }
 156             }
 157         }
 158     }
 159 
 160     public static class NonConstantTest {
 161         public static java.util.Random rnd = new java.util.Random();
 162 
 163         public static void verify(BinaryMethod method) {
 164             for (int i = 0; i < 50000; ++i) {
 165                 int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();
 166                 Verify.verifyBinary(rnd1, rnd2, method);
 167                 Verify.verifyBinary(rnd1, rnd2 + 1, method);
 168                 Verify.verifyBinary(rnd1 + 1, rnd2, method);
 169                 Verify.verifyBinary(rnd1 - 1, rnd2, method);
 170                 Verify.verifyBinary(rnd1, rnd2 - 1, method);
 171             }
 172         }
 173     }
 174 
 175     public static class NonConstantLongTest {
 176         public static long[] values = { Long.MIN_VALUE, Long.MAX_VALUE, 0, Long.MAX_VALUE - 1831 };
 177         public static java.util.Random rnd = new java.util.Random();
 178 
 179         public static void verify(BinaryLongMethod method) {
 180             for (int i = 0; i < 50000; ++i) {
 181                 long rnd1 = rnd.nextLong(), rnd2 = rnd.nextLong();
 182                 Verify.verifyBinary(rnd1, rnd2, method);
 183                 Verify.verifyBinary(rnd1, rnd2 + 1, method);
 184                 Verify.verifyBinary(rnd1 + 1, rnd2, method);
 185                 Verify.verifyBinary(rnd1 - 1, rnd2, method);
 186                 Verify.verifyBinary(rnd1, rnd2 - 1, method);
 187                 Verify.verifyBinary(rnd1 + Long.MAX_VALUE - rnd2, rnd2 + 1, method);
 188                 Verify.verifyBinary(values[0], values[2], method);
 189                 Verify.verifyBinary(values[1], values[2], method);
 190                 Verify.verifyBinary(values[3], 74L, method);
 191             }
 192         }
 193     }
 194 
 195     public static class LoopDependentTest {
 196         public static java.util.Random rnd = new java.util.Random();
 197 
 198         public static void verify(BinaryMethod method) {
 199             int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt();
 200             runTest(rnd1, rnd2, method);
 201         }
 202 
 203         private static void runTest(int rnd1, int rnd2, BinaryMethod method) {
 204             for (int i = 0; i < 50000; ++i) {
 205                 Verify.verifyBinary(rnd1 + i, rnd2 + i, method);
 206                 Verify.verifyBinary(rnd1 + i, rnd2 + (i & 0xff), method);
 207                 Verify.verifyBinary(rnd1 - i, rnd2 - (i & 0xff), method);
 208                 Verify.verifyBinary(rnd1 + i + 1, rnd2 + i + 2, method);
 209                 Verify.verifyBinary(rnd1 + i * 2, rnd2 + i, method);
 210             }
 211         }
 212     }
 213 
 214     public static class ConstantTest {
 215         public static void verify(BinaryMethod method) {
 216             for (int i = 0; i < 50000; ++i) {
 217                 Verify.verifyBinary(5, 7, method);
 218                 Verify.verifyBinary(Integer.MAX_VALUE, 1, method);
 219                 Verify.verifyBinary(Integer.MIN_VALUE, -1, method);
 220                 Verify.verifyBinary(Integer.MAX_VALUE, -1, method);
 221                 Verify.verifyBinary(Integer.MIN_VALUE, 1, method);
 222                 Verify.verifyBinary(Integer.MAX_VALUE / 2, Integer.MAX_VALUE / 2, method);
 223                 Verify.verifyBinary(Integer.MAX_VALUE / 2, (Integer.MAX_VALUE / 2) + 3, method);
 224                 Verify.verifyBinary(Integer.MAX_VALUE, Integer.MIN_VALUE, method);
 225             }
 226         }
 227     }
 228 
 229     public static class ConstantLongTest {
 230         public static void verify(BinaryLongMethod method) {
 231             for (int i = 0; i < 50000; ++i) {
 232                 Verify.verifyBinary(5, 7, method);
 233                 Verify.verifyBinary(Long.MAX_VALUE, 1, method);
 234                 Verify.verifyBinary(Long.MIN_VALUE, -1, method);
 235                 Verify.verifyBinary(Long.MAX_VALUE, -1, method);
 236                 Verify.verifyBinary(Long.MIN_VALUE, 1, method);
 237                 Verify.verifyBinary(Long.MAX_VALUE / 2, Long.MAX_VALUE / 2, method);
 238                 Verify.verifyBinary(Long.MAX_VALUE / 2, (Long.MAX_VALUE / 2) + 3, method);
 239                 Verify.verifyBinary(Long.MAX_VALUE, Long.MIN_VALUE, method);
 240             }
 241         }
 242     }
 243 
 244     public static interface BinaryMethod {
 245         int safeMethod(int a, int b);
 246         int checkMethod(int a, int b);
 247         int unchecked(int a, int b);
 248         String name();
 249     }
 250 
 251     public static interface UnaryMethod {
 252         int safeMethod(int value);
 253         int checkMethod(int value);
 254         int unchecked(int value);
 255         String name();
 256     }
 257 
 258     public static interface BinaryLongMethod {
 259         long safeMethod(long a, long b);
 260         long checkMethod(long a, long b);
 261         long unchecked(long a, long b);
 262         String name();
 263     }
 264 
 265     public static interface UnaryLongMethod {
 266         long safeMethod(long value);
 267         long checkMethod(long value);
 268         long unchecked(long value);
 269         String name();
 270     }
 271 
 272     public static class UnaryToBinary implements BinaryMethod {
 273         private final UnaryMethod method;
 274         public UnaryToBinary(UnaryMethod method) {
 275             this.method = method;
 276         }
 277 
 278         @Override
 279         public int safeMethod(int a, int b) {
 280             return method.safeMethod(a);
 281         }
 282 
 283         @Override
 284         public int checkMethod(int a, int b) {
 285             return method.checkMethod(a);
 286         }
 287 
 288         @Override
 289         public int unchecked(int a, int b) {
 290             return method.unchecked(a);
 291 
 292         }
 293 
 294         @Override
 295         public String name() {
 296             return method.name();
 297         }
 298     }
 299 
 300     public static class UnaryToBinaryLong implements BinaryLongMethod {
 301         private final UnaryLongMethod method;
 302         public UnaryToBinaryLong(UnaryLongMethod method) {
 303             this.method = method;
 304         }
 305 
 306         @Override
 307         public long safeMethod(long a, long b) {
 308             return method.safeMethod(a);
 309         }
 310 
 311         @Override
 312         public long checkMethod(long a, long b) {
 313             return method.checkMethod(a);
 314         }
 315 
 316         @Override
 317         public long unchecked(long a, long b) {
 318             return method.unchecked(a);
 319 
 320         }
 321 
 322         @Override
 323         public String name() {
 324             return method.name();
 325         }
 326     }
 327 
 328 
 329     public static class AddExactI implements BinaryMethod {
 330         @Override
 331         public int safeMethod(int x, int y) {
 332             int r = x + y;
 333             // HD 2-12 Overflow iff both arguments have the opposite sign of the result
 334             if (((x ^ r) & (y ^ r)) < 0) {
 335                 throw new ArithmeticException("integer overflow");
 336             }
 337             return r;
 338 
 339         }
 340 
 341         @Override
 342         public int checkMethod(int a, int b) {
 343             return Math.addExact(a, b);
 344         }
 345 
 346         @Override
 347         public String name() {
 348             return "addExact";
 349         }
 350 
 351         @Override
 352         public int unchecked(int a, int b) {
 353             return a + b;
 354         }
 355     }
 356 
 357     public static class AddExactL implements BinaryLongMethod {
 358         @Override
 359         public long safeMethod(long x, long y) {
 360             long r = x + y;
 361             // HD 2-12 Overflow iff both arguments have the opposite sign of the result
 362             if (((x ^ r) & (y ^ r)) < 0) {
 363                 throw new ArithmeticException("integer overflow");
 364             }
 365             return r;
 366 
 367         }
 368 
 369         @Override
 370         public long checkMethod(long a, long b) {
 371             return Math.addExact(a, b);
 372         }
 373 
 374         @Override
 375         public String name() {
 376             return "addExactLong";
 377         }
 378 
 379         @Override
 380         public long unchecked(long a, long b) {
 381             return a + b;
 382         }
 383     }
 384 
 385     public static class MulExactI implements BinaryMethod {
 386         @Override
 387         public int safeMethod(int x, int y) {
 388             long r = (long)x * (long)y;
 389             if ((int)r != r) {
 390                 throw new ArithmeticException("integer overflow");
 391             }
 392             return (int)r;
 393 
 394         }
 395 
 396         @Override
 397         public int checkMethod(int a, int b) {
 398             return Math.multiplyExact(a, b);
 399         }
 400 
 401         @Override
 402         public int unchecked(int a, int b) {
 403             return a * b;
 404         }
 405 
 406         @Override
 407         public String name() {
 408             return "multiplyExact";
 409         }
 410     }
 411 
 412     public static class MulExactL implements BinaryLongMethod {
 413         @Override
 414         public long safeMethod(long x, long y) {
 415             long r = x * y;
 416             long ax = Math.abs(x);
 417             long ay = Math.abs(y);
 418             if (((ax | ay) >>> 31 != 0)) {
 419                 // Some bits greater than 2^31 that might cause overflow
 420                 // Check the result using the divide operator
 421                 // and check for the special case of Long.MIN_VALUE * -1
 422                 if (((y != 0) && (r / y != x)) ||
 423                         (x == Long.MIN_VALUE && y == -1)) {
 424                     throw new ArithmeticException("long overflow");
 425                 }
 426             }
 427             return r;
 428         }
 429 
 430         @Override
 431         public long checkMethod(long a, long b) {
 432             return Math.multiplyExact(a, b);
 433         }
 434 
 435         @Override
 436         public long unchecked(long a, long b) {
 437             return a * b;
 438         }
 439 
 440         @Override
 441         public String name() {
 442             return "multiplyExact";
 443         }
 444     }
 445 
 446     public static class NegExactL implements UnaryLongMethod {
 447         @Override
 448         public long safeMethod(long a) {
 449             if (a == Long.MIN_VALUE) {
 450                 throw new ArithmeticException("long overflow");
 451             }
 452 
 453             return -a;
 454 
 455         }
 456 
 457         @Override
 458         public long checkMethod(long value) {
 459             return Math.negateExact(value);
 460         }
 461 
 462         @Override
 463         public long unchecked(long value) {
 464             return -value;
 465         }
 466 
 467         @Override
 468         public String name() {
 469             return "negateExactLong";
 470         }
 471     }
 472 
 473     public static class NegExactI implements UnaryMethod {
 474         @Override
 475         public int safeMethod(int a) {
 476             if (a == Integer.MIN_VALUE) {
 477                 throw new ArithmeticException("integer overflow");
 478             }
 479 
 480             return -a;
 481 
 482         }
 483 
 484         @Override
 485         public int checkMethod(int value) {
 486             return Math.negateExact(value);
 487         }
 488 
 489         @Override
 490         public int unchecked(int value) {
 491             return -value;
 492         }
 493 
 494         @Override
 495         public String name() {
 496             return "negateExact";
 497         }
 498     }
 499 
 500     public static class SubExactI implements BinaryMethod {
 501         @Override
 502         public int safeMethod(int x, int y) {
 503             int r = x - y;
 504             // HD 2-12 Overflow iff the arguments have different signs and
 505             // the sign of the result is different than the sign of x
 506             if (((x ^ y) & (x ^ r)) < 0) {
 507                 throw new ArithmeticException("integer overflow");
 508             }
 509             return r;
 510         }
 511 
 512         @Override
 513         public int checkMethod(int a, int b) {
 514             return Math.subtractExact(a, b);
 515         }
 516 
 517         @Override
 518         public int unchecked(int a, int b) {
 519             return a - b;
 520         }
 521 
 522         @Override
 523         public String name() {
 524             return "subtractExact";
 525         }
 526     }
 527 
 528     public static class SubExactL implements BinaryLongMethod {
 529         @Override
 530         public long safeMethod(long x, long y) {
 531             long r = x - y;
 532             // HD 2-12 Overflow iff the arguments have different signs and
 533             // the sign of the result is different than the sign of x
 534             if (((x ^ y) & (x ^ r)) < 0) {
 535                 throw new ArithmeticException("integer overflow");
 536             }
 537             return r;
 538         }
 539 
 540         @Override
 541         public long checkMethod(long a, long b) {
 542             return Math.subtractExact(a, b);
 543         }
 544 
 545         @Override
 546         public long unchecked(long a, long b) {
 547             return a - b;
 548         }
 549 
 550         @Override
 551         public String name() {
 552             return "subtractExactLong";
 553         }
 554     }
 555 
 556     static class IncExactL implements UnaryLongMethod {
 557         @Override
 558         public long safeMethod(long a) {
 559             if (a == Long.MAX_VALUE) {
 560                 throw new ArithmeticException("long overflow");
 561             }
 562 
 563             return a + 1L;
 564 
 565         }
 566 
 567         @Override
 568         public long checkMethod(long value) {
 569             return Math.incrementExact(value);
 570         }
 571 
 572         @Override
 573         public long unchecked(long value) {
 574             return value + 1;
 575         }
 576 
 577         @Override
 578         public String name() {
 579             return "incrementExactLong";
 580         }
 581     }
 582 
 583     static class IncExactI implements UnaryMethod {
 584         @Override
 585         public int safeMethod(int a) {
 586             if (a == Integer.MAX_VALUE) {
 587                 throw new ArithmeticException("integer overflow");
 588             }
 589 
 590             return a + 1;
 591         }
 592 
 593         @Override
 594         public int checkMethod(int value) {
 595             return Math.incrementExact(value);
 596         }
 597 
 598         @Override
 599         public int unchecked(int value) {
 600             return value + 1;
 601         }
 602 
 603         @Override
 604         public String name() {
 605             return "incrementExact";
 606         }
 607     }
 608 
 609     static class DecExactL implements UnaryLongMethod {
 610         @Override
 611         public long safeMethod(long a) {
 612             if (a == Long.MIN_VALUE) {
 613                 throw new ArithmeticException("long overflow");
 614             }
 615 
 616             return a - 1L;
 617         }
 618 
 619         @Override
 620         public long checkMethod(long value) {
 621             return Math.decrementExact(value);
 622         }
 623 
 624         @Override
 625         public long unchecked(long value) {
 626             return value - 1;
 627         }
 628 
 629         @Override
 630         public String name() {
 631             return "decExactLong";
 632         }
 633     }
 634 
 635     static class DecExactI implements UnaryMethod {
 636         @Override
 637         public int safeMethod(int a) {
 638             if (a == Integer.MIN_VALUE) {
 639                 throw new ArithmeticException("integer overflow");
 640             }
 641 
 642             return a - 1;
 643         }
 644 
 645         @Override
 646         public int checkMethod(int value) {
 647             return Math.decrementExact(value);
 648         }
 649 
 650         @Override
 651         public int unchecked(int value) {
 652             return value - 1;
 653         }
 654 
 655         @Override
 656         public String name() {
 657             return "decrementExact";
 658         }
 659     }
 660 
 661 }
test/compiler/intrinsics/mathexact/Verify.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File