test/compiler/intrinsics/mathexact/Verify.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/test/compiler/intrinsics/mathexact/Verify.java Fri Oct 18 10:43:09 2013
--- new/test/compiler/intrinsics/mathexact/Verify.java Fri Oct 18 10:43:09 2013
*** 24,68 ****
--- 24,661 ----
public class Verify {
public static String throwWord(boolean threw) {
return (threw ? "threw" : "didn't throw");
}
! public static void verify(int a, int b) {
! 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 = testIntrinsic(a, b);
! result1 = method.checkMethod(a);
} catch (ArithmeticException e) {
exception1 = true;
}
try {
! result2 = testNonIntrinsic(a, b);
! result2 = method.safeMethod(a);
} catch (ArithmeticException e) {
exception2 = true;
}
if (exception1 != exception2) {
throw new RuntimeException("Intrinsic version " + throwWord(exception1) + " exception, NonIntrinsic version " + throwWord(exception2) + " for: " + a + " + " + b);
+ verifyResult(method, result1, result2, exception1, exception2, a);
}
if (result1 != result2) {
throw new RuntimeException("Intrinsic version returned: " + a + " while NonIntrinsic version returned: " + b);
+
+ 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 int testIntrinsic(int a, int b) {
return java.lang.Math.addExact(a, b);
! 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);
+ }
+ }
+ }
+ }
+
+ 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 int testNonIntrinsic(int a, int b) {
! return safeAddExact(a, b);
! public static interface UnaryLongMethod {
! long safeMethod(long value);
+ long checkMethod(long value);
+ long unchecked(long value);
+ String name();
}
// Copied java.lang.Math.addExact to avoid intrinsification
public static int safeAddExact(int x, int y) {
+ 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