using System; using System.Reflection; /* * Regression tests for the mono JIT. * * Each test needs to be of the form: * * public static int test__ (); * * where is an integer (the value that needs to be returned by * the method to make it pass. * is a user-displayed name used to identify the test. * * The tests can be driven in two ways: * *) running the program directly: Main() uses reflection to find and invoke * the test methods (this is useful mostly to check that the tests are correct) * *) with the --regression switch of the jit (this is the preferred way since * all the tests will be run with optimizations on and off) * * The reflection logic could be moved to a .dll since we need at least another * regression test file written in IL code to have better control on how * the IL code looks. */ public partial class Tests { public static int test_0_sin_precision() { double d1 = Math.Sin(1); double d2 = Math.Sin(1) - d1; return (d2 == 0) ? 0 : 1; } public static int test_0_cos_precision() { double d1 = Math.Cos(1); double d2 = Math.Cos(1) - d1; return (d2 == 0) ? 0 : 1; } public static int test_0_tan_precision() { double d1 = Math.Tan(1); double d2 = Math.Tan(1) - d1; return (d2 == 0) ? 0 : 1; } public static int test_0_atan_precision() { double d1 = Math.Atan(double.NegativeInfinity); double d2 = Math.Atan(double.NegativeInfinity) - d1; return (d2 == 0) ? 0 : 1; } public static int test_0_sqrt_precision() { double d1 = Math.Sqrt(2); double d2 = Math.Sqrt(2) - d1; return (d2 == 0) ? 0 : 1; } public static int test_2_sqrt() { return (int)Math.Sqrt(4); } public static int test_0_sqrt_precision_and_not_spill() { double expected = 0; double[] operands = new double[3]; double[] temporaries = new double[3]; for (int i = 0; i < 3; i++) { operands[i] = (i + 1) * (i + 1) * (i + 1); if (i == 0) { expected = operands[0]; } else { temporaries[i] = operands[i] / expected; temporaries[i] = Math.Sqrt(temporaries[i]); expected = temporaries[i]; } //Console.Write( "{0}: {1}\n", i, temporaries [i] ); } expected = temporaries[2]; double result = Math.Sqrt(operands[2] / Math.Sqrt(operands[1] / operands[0])); //Console.Write( "result: {0,20:G}\n", result ); return (result == expected) ? 0 : 1; } public static int test_0_sqrt_precision_and_spill() { double expected = 0; double[] operands = new double[9]; double[] temporaries = new double[9]; for (int i = 0; i < 9; i++) { operands[i] = (i + 1) * (i + 1) * (i + 1); if (i == 0) { expected = operands[0]; } else { temporaries[i] = operands[i] / expected; temporaries[i] = Math.Sqrt(temporaries[i]); expected = temporaries[i]; } //Console.Write( "{0}: {1}\n", i, temporaries [i] ); } expected = temporaries[8]; double result = Math.Sqrt(operands[8] / Math.Sqrt(operands[7] / Math.Sqrt(operands[6] / Math.Sqrt(operands[5] / Math.Sqrt(operands[4] / Math.Sqrt(operands[3] / Math.Sqrt(operands[2] / Math.Sqrt(operands[1] / operands[0])))))))); //Console.Write( "result: {0,20:G}\n", result ); return (result == expected) ? 0 : 1; } public static int test_0_div_precision_and_spill() { double expected = 0; double[] operands = new double[9]; double[] temporaries = new double[9]; for (int i = 0; i < 9; i++) { operands[i] = (i + 1) * (i + 1); if (i == 0) { expected = operands[0]; } else { temporaries[i] = operands[i] / expected; expected = temporaries[i]; } //Console.Write( "{0}: {1}\n", i, temporaries [i] ); } expected = temporaries[8]; double result = (operands[8] / (operands[7] / (operands[6] / (operands[5] / (operands[4] / (operands[3] / (operands[2] / (operands[1] / operands[0])))))))); //Console.Write( "result: {0,20:G}\n", result ); return (result == expected) ? 0 : 1; } public static int test_0_sqrt_nan() { return Double.IsNaN(Math.Sqrt(Double.NaN)) ? 0 : 1; } public static int test_0_sin_nan() { return Double.IsNaN(Math.Sin(Double.NaN)) ? 0 : 1; } public static int test_0_cos_nan() { return Double.IsNaN(Math.Cos(Double.NaN)) ? 0 : 1; } public static int test_0_tan_nan() { return Double.IsNaN(Math.Tan(Double.NaN)) ? 0 : 1; } public static int test_0_atan_nan() { return Double.IsNaN(Math.Atan(Double.NaN)) ? 0 : 1; } public static int test_0_min() { if (Math.Min(5, 6) != 5) return 1; if (Math.Min(6, 5) != 5) return 2; if (Math.Min(-100, -101) != -101) return 3; if (Math.Min((long)5, (long)6) != 5) return 4; if (Math.Min((long)6, (long)5) != 5) return 5; if (Math.Min((long)-100, (long)-101) != -101) return 6; return 0; } public static int test_0_max() { if (Math.Max(5, 6) != 6) return 1; if (Math.Max(6, 5) != 6) return 2; if (Math.Max(-100, -101) != -100) return 3; if (Math.Max((long)5, (long)6) != 6) return 4; if (Math.Max((long)6, (long)5) != 6) return 5; if (Math.Max((long)-100, (long)-101) != -100) return 6; return 0; } public static int test_0_min_un() { uint a = (uint)int.MaxValue + 10; for (uint b = 7; b <= 10; ++b) { if (Math.Min(a, b) != b) return (int)b; if (Math.Min(b, a) != b) return (int)b; } if (Math.Min((ulong)5, (ulong)6) != 5) return 4; if (Math.Min((ulong)6, (ulong)5) != 5) return 5; ulong la = (ulong)long.MaxValue + 10; for (ulong b = 7; b <= 10; ++b) { if (Math.Min(la, b) != b) return (int)b; if (Math.Min(b, la) != b) return (int)b; } return 0; } public static int test_0_max_un() { uint a = (uint)int.MaxValue + 10; for (uint b = 7; b <= 10; ++b) { if (Math.Max(a, b) != a) return (int)b; if (Math.Max(b, a) != a) return (int)b; } if (Math.Max((ulong)5, (ulong)6) != 6) return 4; if (Math.Max((ulong)6, (ulong)5) != 6) return 5; ulong la = (ulong)long.MaxValue + 10; for (ulong b = 7; b <= 10; ++b) { if (Math.Max(la, b) != la) return (int)b; if (Math.Max(b, la) != la) return (int)b; } return 0; } public static int test_0_abs() { double d = -5.0; if (Math.Abs(d) != 5.0) return 1; return 0; } public static int test_0_round() { if (Math.Round(5.0) != 5.0) return 1; if (Math.Round(5.000000000000001) != 5.0) return 2; if (Math.Round(5.499999999999999) != 5.0) return 3; if (Math.Round(5.5) != 6.0) return 4; if (Math.Round(5.999999999999999) != 6.0) return 5; if (Math.Round(Double.Epsilon) != 0) return 6; if (!Double.IsNaN(Math.Round(Double.NaN))) return 7; if (!Double.IsPositiveInfinity(Math.Round(Double.PositiveInfinity))) return 8; if (!Double.IsNegativeInfinity(Math.Round(Double.NegativeInfinity))) return 9; if (Math.Round(Double.MinValue) != Double.MinValue) return 10; if (Math.Round(Double.MaxValue) != Double.MaxValue) return 11; return 0; } }