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

test/compiler/intrinsics/mathexact/Verify.java

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

*** 24,68 **** public class Verify { public static String throwWord(boolean threw) { return (threw ? "threw" : "didn't throw"); } ! public static void verify(int a, int b) { boolean exception1 = false, exception2 = false; int result1 = 0, result2 = 0; try { ! result1 = testIntrinsic(a, b); } catch (ArithmeticException e) { exception1 = true; } try { ! result2 = testNonIntrinsic(a, b); } catch (ArithmeticException e) { exception2 = true; } ! if (exception1 != exception2) { ! throw new RuntimeException("Intrinsic version " + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b); } ! if (result1 != result2) { ! throw new RuntimeException("Intrinsic version returned: " + a + " while NonIntrinsic version returned: " + b); } } ! public static int testIntrinsic(int a, int b) { ! return java.lang.Math.addExact(a, b); } ! public static int testNonIntrinsic(int a, int b) { ! return safeAddExact(a, b); } ! // Copied java.lang.Math.addExact to avoid intrinsification ! public static int safeAddExact(int x, int y) { int r = x + y; // HD 2-12 Overflow iff both arguments have the opposite sign of the result if (((x ^ r) & (y ^ r)) < 0) { throw new ArithmeticException("integer overflow"); } return r; } } --- 24,662 ---- public class Verify { public static String throwWord(boolean threw) { return (threw ? "threw" : "didn't throw"); } ! public static void verifyResult(UnaryMethod method, int result1, int result2, boolean exception1, boolean exception2, int value) { ! if (exception1 != exception2) { ! throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version" + throwWord(exception2) + " for: " + value); ! } ! if (result1 != result2) { ! throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2); ! } ! } ! ! public static void verifyResult(UnaryLongMethod method, long result1, long result2, boolean exception1, boolean exception2, long value) { ! if (exception1 != exception2) { ! throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version" + throwWord(exception2) + " for: " + value); ! } ! if (result1 != result2) { ! throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2); ! } ! } ! ! private static void verifyResult(BinaryMethod method, int result1, int result2, boolean exception1, boolean exception2, int a, int b) { ! if (exception1 != exception2) { ! throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b); ! } ! if (result1 != result2) { ! throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2); ! } ! } ! ! private static void verifyResult(BinaryLongMethod method, long result1, long result2, boolean exception1, boolean exception2, long a, long b) { ! if (exception1 != exception2) { ! throw new RuntimeException("Intrinsic version [" + method.name() + "]" + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b); ! } ! if (result1 != result2) { ! throw new RuntimeException("Intrinsic version [" + method.name() + "] returned: " + result1 + " while NonIntrinsic version returned: " + result2); ! } ! } ! ! ! public static void verifyUnary(int a, UnaryMethod method) { boolean exception1 = false, exception2 = false; int result1 = 0, result2 = 0; try { ! result1 = method.checkMethod(a); } catch (ArithmeticException e) { exception1 = true; } try { ! result2 = method.safeMethod(a); } catch (ArithmeticException e) { exception2 = true; } ! verifyResult(method, result1, result2, exception1, exception2, a); } ! ! public static void verifyUnary(long a, UnaryLongMethod method) { ! boolean exception1 = false, exception2 = false; ! long result1 = 0, result2 = 0; ! try { ! result1 = method.checkMethod(a); ! } catch (ArithmeticException e) { ! exception1 = true; ! } ! try { ! result2 = method.safeMethod(a); ! } catch (ArithmeticException e) { ! exception2 = true; ! } ! ! verifyResult(method, result1, result2, exception1, exception2, a); ! } ! ! ! public static void verifyBinary(int a, int b, BinaryMethod method) { ! boolean exception1 = false, exception2 = false; ! int result1 = 0, result2 = 0; ! try { ! result1 = method.checkMethod(a, b); ! } catch (ArithmeticException e) { ! exception1 = true; ! } ! try { ! result2 = method.safeMethod(a, b); ! } catch (ArithmeticException e) { ! exception2 = true; ! } ! ! verifyResult(method, result1, result2, exception1, exception2, a, b); ! } ! ! public static void verifyBinary(long a, long b, BinaryLongMethod method) { ! boolean exception1 = false, exception2 = false; ! long result1 = 0, result2 = 0; ! try { ! result1 = method.checkMethod(a, b); ! } catch (ArithmeticException e) { ! exception1 = true; ! } ! try { ! result2 = method.safeMethod(a, b); ! } catch (ArithmeticException e) { ! exception2 = true; ! } ! ! verifyResult(method, result1, result2, exception1, exception2, a, b); ! } ! ! ! public static class LoadTest { ! public static java.util.Random rnd = new java.util.Random(); ! public static int[] values = new int[256]; ! ! public static void init() { ! for (int i = 0; i < values.length; ++i) { ! values[i] = rnd.nextInt(); } } ! public static void verify(BinaryMethod method) { ! for (int i = 0; i < 50000; ++i) { ! Verify.verifyBinary(values[i & 255], values[i & 255] - i, method); ! Verify.verifyBinary(values[i & 255] + i, values[i & 255] - i, method); ! Verify.verifyBinary(values[i & 255], values[i & 255], method); ! if ((i & 1) == 1 && i > 5) { ! Verify.verifyBinary(values[i & 255] + i, values[i & 255] - i, method); ! } else { ! Verify.verifyBinary(values[i & 255] - i, values[i & 255] + i, method); ! } ! Verify.verifyBinary(values[i & 255], values[(i + 1) & 255], method); ! } ! } ! } ! ! public static class NonConstantTest { ! public static java.util.Random rnd = new java.util.Random(); ! ! public static void verify(BinaryMethod method) { ! for (int i = 0; i < 50000; ++i) { ! int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt(); ! Verify.verifyBinary(rnd1, rnd2, method); ! Verify.verifyBinary(rnd1, rnd2 + 1, method); ! Verify.verifyBinary(rnd1 + 1, rnd2, method); ! Verify.verifyBinary(rnd1 - 1, rnd2, method); ! Verify.verifyBinary(rnd1, rnd2 - 1, method); ! } ! } ! } ! ! public static class NonConstantLongTest { ! public static long[] values = { Long.MIN_VALUE, Long.MAX_VALUE, 0, Long.MAX_VALUE - 1831 }; ! public static java.util.Random rnd = new java.util.Random(); ! ! public static void verify(BinaryLongMethod method) { ! for (int i = 0; i < 50000; ++i) { ! long rnd1 = rnd.nextLong(), rnd2 = rnd.nextLong(); ! Verify.verifyBinary(rnd1, rnd2, method); ! Verify.verifyBinary(rnd1, rnd2 + 1, method); ! Verify.verifyBinary(rnd1 + 1, rnd2, method); ! Verify.verifyBinary(rnd1 - 1, rnd2, method); ! Verify.verifyBinary(rnd1, rnd2 - 1, method); ! Verify.verifyBinary(rnd1 + Long.MAX_VALUE - rnd2, rnd2 + 1, method); ! Verify.verifyBinary(values[0], values[2], method); ! Verify.verifyBinary(values[1], values[2], method); ! Verify.verifyBinary(values[3], 74L, method); ! } ! } ! } ! ! public static class LoopDependentTest { ! public static java.util.Random rnd = new java.util.Random(); ! ! public static void verify(BinaryMethod method) { ! int rnd1 = rnd.nextInt(), rnd2 = rnd.nextInt(); ! runTest(rnd1, rnd2, method); ! } ! ! private static void runTest(int rnd1, int rnd2, BinaryMethod method) { ! for (int i = 0; i < 50000; ++i) { ! Verify.verifyBinary(rnd1 + i, rnd2 + i, method); ! Verify.verifyBinary(rnd1 + i, rnd2 + (i & 0xff), method); ! Verify.verifyBinary(rnd1 - i, rnd2 - (i & 0xff), method); ! Verify.verifyBinary(rnd1 + i + 1, rnd2 + i + 2, method); ! Verify.verifyBinary(rnd1 + i * 2, rnd2 + i, method); ! } ! } ! } ! ! public static class ConstantTest { ! public static void verify(BinaryMethod method) { ! for (int i = 0; i < 50000; ++i) { ! Verify.verifyBinary(5, 7, method); ! Verify.verifyBinary(Integer.MAX_VALUE, 1, method); ! Verify.verifyBinary(Integer.MIN_VALUE, -1, method); ! Verify.verifyBinary(Integer.MAX_VALUE, -1, method); ! Verify.verifyBinary(Integer.MIN_VALUE, 1, method); ! Verify.verifyBinary(Integer.MAX_VALUE / 2, Integer.MAX_VALUE / 2, method); ! Verify.verifyBinary(Integer.MAX_VALUE / 2, (Integer.MAX_VALUE / 2) + 3, method); ! Verify.verifyBinary(Integer.MAX_VALUE, Integer.MIN_VALUE, method); ! } ! } ! } ! ! public static class ConstantLongTest { ! public static void verify(BinaryLongMethod method) { ! for (int i = 0; i < 50000; ++i) { ! Verify.verifyBinary(5, 7, method); ! Verify.verifyBinary(Long.MAX_VALUE, 1, method); ! Verify.verifyBinary(Long.MIN_VALUE, -1, method); ! Verify.verifyBinary(Long.MAX_VALUE, -1, method); ! Verify.verifyBinary(Long.MIN_VALUE, 1, method); ! Verify.verifyBinary(Long.MAX_VALUE / 2, Long.MAX_VALUE / 2, method); ! Verify.verifyBinary(Long.MAX_VALUE / 2, (Long.MAX_VALUE / 2) + 3, method); ! Verify.verifyBinary(Long.MAX_VALUE, Long.MIN_VALUE, method); ! } ! } ! } ! ! public static interface BinaryMethod { ! int safeMethod(int a, int b); ! int checkMethod(int a, int b); ! int unchecked(int a, int b); ! String name(); ! } ! ! public static interface UnaryMethod { ! int safeMethod(int value); ! int checkMethod(int value); ! int unchecked(int value); ! String name(); ! } ! ! public static interface BinaryLongMethod { ! long safeMethod(long a, long b); ! long checkMethod(long a, long b); ! long unchecked(long a, long b); ! String name(); } ! public static interface UnaryLongMethod { ! long safeMethod(long value); ! long checkMethod(long value); ! long unchecked(long value); ! String name(); } ! public static class UnaryToBinary implements BinaryMethod { ! private final UnaryMethod method; ! public UnaryToBinary(UnaryMethod method) { ! this.method = method; ! } ! ! @Override ! public int safeMethod(int a, int b) { ! return method.safeMethod(a); ! } ! ! @Override ! public int checkMethod(int a, int b) { ! return method.checkMethod(a); ! } ! ! @Override ! public int unchecked(int a, int b) { ! return method.unchecked(a); ! ! } ! ! @Override ! public String name() { ! return method.name(); ! } ! } ! ! public static class UnaryToBinaryLong implements BinaryLongMethod { ! private final UnaryLongMethod method; ! public UnaryToBinaryLong(UnaryLongMethod method) { ! this.method = method; ! } ! ! @Override ! public long safeMethod(long a, long b) { ! return method.safeMethod(a); ! } ! ! @Override ! public long checkMethod(long a, long b) { ! return method.checkMethod(a); ! } ! ! @Override ! public long unchecked(long a, long b) { ! return method.unchecked(a); ! ! } ! ! @Override ! public String name() { ! return method.name(); ! } ! } ! ! ! public static class AddExactI implements BinaryMethod { ! @Override ! public int safeMethod(int x, int y) { int r = x + y; // HD 2-12 Overflow iff both arguments have the opposite sign of the result if (((x ^ r) & (y ^ r)) < 0) { throw new ArithmeticException("integer overflow"); } return r; + } + + @Override + public int checkMethod(int a, int b) { + return Math.addExact(a, b); + } + + @Override + public String name() { + return "addExact"; + } + + @Override + public int unchecked(int a, int b) { + return a + b; + } + } + + public static class AddExactL implements BinaryLongMethod { + @Override + public long safeMethod(long x, long y) { + long r = x + y; + // HD 2-12 Overflow iff both arguments have the opposite sign of the result + if (((x ^ r) & (y ^ r)) < 0) { + throw new ArithmeticException("integer overflow"); + } + return r; + + } + + @Override + public long checkMethod(long a, long b) { + return Math.addExact(a, b); + } + + @Override + public String name() { + return "addExactLong"; + } + + @Override + public long unchecked(long a, long b) { + return a + b; + } + } + + public static class MulExactI implements BinaryMethod { + @Override + public int safeMethod(int x, int y) { + long r = (long)x * (long)y; + if ((int)r != r) { + throw new ArithmeticException("integer overflow"); + } + return (int)r; + + } + + @Override + public int checkMethod(int a, int b) { + return Math.multiplyExact(a, b); + } + + @Override + public int unchecked(int a, int b) { + return a * b; + } + + @Override + public String name() { + return "multiplyExact"; + } + } + + public static class MulExactL implements BinaryLongMethod { + @Override + public long safeMethod(long x, long y) { + long r = x * y; + long ax = Math.abs(x); + long ay = Math.abs(y); + if (((ax | ay) >>> 31 != 0)) { + // Some bits greater than 2^31 that might cause overflow + // Check the result using the divide operator + // and check for the special case of Long.MIN_VALUE * -1 + if (((y != 0) && (r / y != x)) || + (x == Long.MIN_VALUE && y == -1)) { + throw new ArithmeticException("long overflow"); + } + } + return r; + } + + @Override + public long checkMethod(long a, long b) { + return Math.multiplyExact(a, b); + } + + @Override + public long unchecked(long a, long b) { + return a * b; + } + + @Override + public String name() { + return "multiplyExact"; + } + } + + public static class NegExactL implements UnaryLongMethod { + @Override + public long safeMethod(long a) { + if (a == Long.MIN_VALUE) { + throw new ArithmeticException("long overflow"); + } + + return -a; + + } + + @Override + public long checkMethod(long value) { + return Math.negateExact(value); + } + + @Override + public long unchecked(long value) { + return -value; + } + + @Override + public String name() { + return "negateExactLong"; + } + } + + public static class NegExactI implements UnaryMethod { + @Override + public int safeMethod(int a) { + if (a == Integer.MIN_VALUE) { + throw new ArithmeticException("integer overflow"); + } + + return -a; + + } + + @Override + public int checkMethod(int value) { + return Math.negateExact(value); + } + + @Override + public int unchecked(int value) { + return -value; + } + + @Override + public String name() { + return "negateExact"; + } + } + + public static class SubExactI implements BinaryMethod { + @Override + public int safeMethod(int x, int y) { + int r = x - y; + // HD 2-12 Overflow iff the arguments have different signs and + // the sign of the result is different than the sign of x + if (((x ^ y) & (x ^ r)) < 0) { + throw new ArithmeticException("integer overflow"); + } + return r; + } + + @Override + public int checkMethod(int a, int b) { + return Math.subtractExact(a, b); + } + + @Override + public int unchecked(int a, int b) { + return a - b; + } + + @Override + public String name() { + return "subtractExact"; + } + } + + public static class SubExactL implements BinaryLongMethod { + @Override + public long safeMethod(long x, long y) { + long r = x - y; + // HD 2-12 Overflow iff the arguments have different signs and + // the sign of the result is different than the sign of x + if (((x ^ y) & (x ^ r)) < 0) { + throw new ArithmeticException("integer overflow"); + } + return r; + } + + @Override + public long checkMethod(long a, long b) { + return Math.subtractExact(a, b); + } + + @Override + public long unchecked(long a, long b) { + return a - b; + } + + @Override + public String name() { + return "subtractExactLong"; + } + } + + static class IncExactL implements UnaryLongMethod { + @Override + public long safeMethod(long a) { + if (a == Long.MAX_VALUE) { + throw new ArithmeticException("long overflow"); + } + + return a + 1L; + + } + + @Override + public long checkMethod(long value) { + return Math.incrementExact(value); + } + + @Override + public long unchecked(long value) { + return value + 1; + } + + @Override + public String name() { + return "incrementExactLong"; + } + } + + static class IncExactI implements UnaryMethod { + @Override + public int safeMethod(int a) { + if (a == Integer.MAX_VALUE) { + throw new ArithmeticException("integer overflow"); + } + + return a + 1; + } + + @Override + public int checkMethod(int value) { + return Math.incrementExact(value); + } + + @Override + public int unchecked(int value) { + return value + 1; + } + + @Override + public String name() { + return "incrementExact"; + } + } + + static class DecExactL implements UnaryLongMethod { + @Override + public long safeMethod(long a) { + if (a == Long.MIN_VALUE) { + throw new ArithmeticException("long overflow"); + } + + return a - 1L; + } + + @Override + public long checkMethod(long value) { + return Math.decrementExact(value); + } + + @Override + public long unchecked(long value) { + return value - 1; + } + + @Override + public String name() { + return "decExactLong"; + } + } + + static class DecExactI implements UnaryMethod { + @Override + public int safeMethod(int a) { + if (a == Integer.MIN_VALUE) { + throw new ArithmeticException("integer overflow"); + } + + return a - 1; + } + + @Override + public int checkMethod(int value) { + return Math.decrementExact(value); + } + + @Override + public int unchecked(int value) { + return value - 1; + } + + @Override + public String name() { + return "decrementExact"; + } + } + }
test/compiler/intrinsics/mathexact/Verify.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File