diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 955a7bba1e9a9..35b01ad27ec43 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -14458,46 +14458,26 @@ GenTree* Compiler::gtFoldExprConst(GenTree* tree) break; case GT_CAST: + f1 = forceCastToFloat(d1); - if (tree->gtOverflow() && - ((op1->TypeIs(TYP_DOUBLE) && CheckedOps::CastFromDoubleOverflows(d1, tree->CastToType())) || - (op1->TypeIs(TYP_FLOAT) && - CheckedOps::CastFromFloatOverflows(forceCastToFloat(d1), tree->CastToType())))) + if ((op1->TypeIs(TYP_DOUBLE) && CheckedOps::CastFromDoubleOverflows(d1, tree->CastToType())) || + (op1->TypeIs(TYP_FLOAT) && CheckedOps::CastFromFloatOverflows(f1, tree->CastToType()))) { - return tree; - } + // The conversion overflows. The ECMA spec says, in III 3.27, that + // "...if overflow occurs converting a floating point type to an integer, ..., + // the value returned is unspecified." However, it would at least be + // desirable to have the same value returned for casting an overflowing + // constant to an int as would be obtained by passing that constant as + // a parameter and then casting that parameter to an int type. - assert(tree->TypeIs(genActualType(tree->CastToType()))); + // Don't fold overflowing converions, as the value returned by + // JIT's codegen doesn't always match with the C compiler's cast result. + // We want the behavior to be the same with or without folding. - if ((op1->TypeIs(TYP_FLOAT) && !_finite(forceCastToFloat(d1))) || - (op1->TypeIs(TYP_DOUBLE) && !_finite(d1))) - { - // The floating point constant is not finite. The ECMA spec says, in - // III 3.27, that "...if overflow occurs converting a floating point type - // to an integer, ..., the value returned is unspecified." However, it would - // at least be desirable to have the same value returned for casting an overflowing - // constant to an int as would obtained by passing that constant as a parameter - // then casting that parameter to an int type. We will assume that the C compiler's - // cast logic will yield the desired result (and trust testing to tell otherwise). - // Cross-compilation is an issue here; if that becomes an important scenario, we should - // capture the target-specific values of overflow casts to the various integral types as - // constants in a target-specific function. - CLANG_FORMAT_COMMENT_ANCHOR; - - // Don't fold conversions of +inf/-inf to integral value on all platforms - // as the value returned by JIT helper doesn't match with the C compiler's cast result. - // We want the behavior to be same with or without folding. return tree; } - if (d1 <= -1.0 && varTypeIsUnsigned(tree->CastToType())) - { - // Don't fold conversions of these cases becasue the result is unspecified per ECMA spec - // and the native math doing the fold doesn't match the run-time computation on all - // platforms. - // We want the behavior to be same with or without folding. - return tree; - } + assert(tree->TypeIs(genActualType(tree->CastToType()))); switch (tree->CastToType()) { diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index e49ba55eca816..110730f15e6c5 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -3012,7 +3012,7 @@ ValueNum ValueNumStore::EvalCastForConstantArgs(var_types typ, VNFunc func, Valu case TYP_FLOAT: { float arg0Val = GetConstantSingle(arg0VN); - assert(!checkedCast || !CheckedOps::CastFromFloatOverflows(arg0Val, castToType)); + assert(!CheckedOps::CastFromFloatOverflows(arg0Val, castToType)); switch (castToType) { @@ -3054,7 +3054,7 @@ ValueNum ValueNumStore::EvalCastForConstantArgs(var_types typ, VNFunc func, Valu case TYP_DOUBLE: { double arg0Val = GetConstantDouble(arg0VN); - assert(!checkedCast || !CheckedOps::CastFromDoubleOverflows(arg0Val, castToType)); + assert(!CheckedOps::CastFromDoubleOverflows(arg0Val, castToType)); switch (castToType) { @@ -3322,26 +3322,32 @@ bool ValueNumStore::VNEvalShouldFold(var_types typ, VNFunc func, ValueNum arg0VN } } - // Is this a checked cast that will always throw an exception? - if (func == VNF_CastOvf) + // Is this a checked cast that will always throw an exception or one with an implementation-defined result? + if (VNFuncIsNumericCast(func)) { - var_types castToType; - bool fromUnsigned; - GetCastOperFromVN(arg1VN, &castToType, &fromUnsigned); var_types castFromType = TypeOfVN(arg0VN); - switch (castFromType) + // By policy, we do not fold conversions from floating-point types that result in + // overflow, as the value the C++ compiler gives us does not always match our own codegen. + if ((func == VNF_CastOvf) || varTypeIsFloating(castFromType)) { - case TYP_INT: - return !CheckedOps::CastFromIntOverflows(GetConstantInt32(arg0VN), castToType, fromUnsigned); - case TYP_LONG: - return !CheckedOps::CastFromLongOverflows(GetConstantInt64(arg0VN), castToType, fromUnsigned); - case TYP_FLOAT: - return !CheckedOps::CastFromFloatOverflows(GetConstantSingle(arg0VN), castToType); - case TYP_DOUBLE: - return !CheckedOps::CastFromDoubleOverflows(GetConstantDouble(arg0VN), castToType); - default: - return false; + var_types castToType; + bool fromUnsigned; + GetCastOperFromVN(arg1VN, &castToType, &fromUnsigned); + + switch (castFromType) + { + case TYP_INT: + return !CheckedOps::CastFromIntOverflows(GetConstantInt32(arg0VN), castToType, fromUnsigned); + case TYP_LONG: + return !CheckedOps::CastFromLongOverflows(GetConstantInt64(arg0VN), castToType, fromUnsigned); + case TYP_FLOAT: + return !CheckedOps::CastFromFloatOverflows(GetConstantSingle(arg0VN), castToType); + case TYP_DOUBLE: + return !CheckedOps::CastFromDoubleOverflows(GetConstantDouble(arg0VN), castToType); + default: + return false; + } } } diff --git a/src/libraries/System.Linq.Expressions/tests/Convert/ConvertTests.cs b/src/libraries/System.Linq.Expressions/tests/Convert/ConvertTests.cs index cf2242b414126..eb7d20b6ac771 100644 --- a/src/libraries/System.Linq.Expressions/tests/Convert/ConvertTests.cs +++ b/src/libraries/System.Linq.Expressions/tests/Convert/ConvertTests.cs @@ -1650,7 +1650,6 @@ public static void ConvertDoubleToNullableShortTest(bool useInterpreter) } [Theory, ClassData(typeof(CompilationTypes))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/13651")] public static void ConvertDoubleToUIntTest(bool useInterpreter) { foreach (double value in new double[] { 0, 1, -1, double.MinValue, double.MaxValue, double.Epsilon, double.NegativeInfinity, double.PositiveInfinity, double.NaN }) @@ -1660,7 +1659,6 @@ public static void ConvertDoubleToUIntTest(bool useInterpreter) } [Theory, ClassData(typeof(CompilationTypes))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/13651")] public static void ConvertDoubleToNullableUIntTest(bool useInterpreter) { foreach (double value in new double[] { 0, 1, -1, double.MinValue, double.MaxValue, double.Epsilon, double.NegativeInfinity, double.PositiveInfinity, double.NaN }) @@ -1679,7 +1677,6 @@ public static void ConvertDoubleToULongTest(bool useInterpreter) } [Theory, ClassData(typeof(CompilationTypes))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/51346", TestRuntimes.CoreCLR)] public static void ConvertDoubleToNullableULongTest(bool useInterpreter) { foreach (double value in new double[] { 0, 1, -1, double.MinValue, double.MaxValue, double.Epsilon, double.NegativeInfinity, double.PositiveInfinity, double.NaN }) @@ -1905,7 +1902,6 @@ public static void ConvertNullableDoubleToNullableShortTest(bool useInterpreter) } [Theory, ClassData(typeof(CompilationTypes))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/51346", TestRuntimes.CoreCLR)] public static void ConvertNullableDoubleToUIntTest(bool useInterpreter) { foreach (double? value in new double?[] { null, 0, 1, -1, double.MinValue, double.MaxValue, double.Epsilon, double.NegativeInfinity, double.PositiveInfinity, double.NaN }) @@ -1915,7 +1911,6 @@ public static void ConvertNullableDoubleToUIntTest(bool useInterpreter) } [Theory, ClassData(typeof(CompilationTypes))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/51346", TestRuntimes.CoreCLR)] public static void ConvertNullableDoubleToNullableUIntTest(bool useInterpreter) { foreach (double? value in new double?[] { null, 0, 1, -1, double.MinValue, double.MaxValue, double.Epsilon, double.NegativeInfinity, double.PositiveInfinity, double.NaN }) @@ -1934,7 +1929,6 @@ public static void ConvertNullableDoubleToULongTest(bool useInterpreter) } [Theory, ClassData(typeof(CompilationTypes))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/51346", TestRuntimes.CoreCLR)] public static void ConvertNullableDoubleToNullableULongTest(bool useInterpreter) { foreach (double? value in new double?[] { null, 0, 1, -1, double.MinValue, double.MaxValue, double.Epsilon, double.NegativeInfinity, double.PositiveInfinity, double.NaN }) @@ -3096,7 +3090,6 @@ public static void ConvertFloatToNullableShortTest(bool useInterpreter) } [Theory, ClassData(typeof(CompilationTypes))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/47374", TestRuntimes.CoreCLR)] public static void ConvertFloatToUIntTest(bool useInterpreter) { foreach (float value in new float[] { 0, 1, -1, float.MinValue, float.MaxValue, float.Epsilon, float.NegativeInfinity, float.PositiveInfinity, float.NaN }) @@ -3106,7 +3099,6 @@ public static void ConvertFloatToUIntTest(bool useInterpreter) } [Theory, ClassData(typeof(CompilationTypes))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/47374", TestRuntimes.CoreCLR)] public static void ConvertFloatToNullableUIntTest(bool useInterpreter) { foreach (float value in new float[] { 0, 1, -1, float.MinValue, float.MaxValue, float.Epsilon, float.NegativeInfinity, float.PositiveInfinity, float.NaN }) @@ -3124,9 +3116,7 @@ public static void ConvertFloatToULongTest(bool useInterpreter) } } - [Theory, ClassData(typeof(CompilationTypes))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/51346", TestRuntimes.CoreCLR)] public static void ConvertFloatToNullableULongTest(bool useInterpreter) { foreach (float value in new float[] { 0, 1, -1, float.MinValue, float.MaxValue, float.Epsilon, float.NegativeInfinity, float.PositiveInfinity, float.NaN }) @@ -3352,7 +3342,6 @@ public static void ConvertNullableFloatToNullableShortTest(bool useInterpreter) } [Theory, ClassData(typeof(CompilationTypes))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/51346", TestRuntimes.CoreCLR)] public static void ConvertNullableFloatToUIntTest(bool useInterpreter) { foreach (float? value in new float?[] { null, 0, 1, -1, float.MinValue, float.MaxValue, float.Epsilon, float.NegativeInfinity, float.PositiveInfinity, float.NaN }) @@ -3362,7 +3351,6 @@ public static void ConvertNullableFloatToUIntTest(bool useInterpreter) } [Theory, ClassData(typeof(CompilationTypes))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/51346", TestRuntimes.CoreCLR)] public static void ConvertNullableFloatToNullableUIntTest(bool useInterpreter) { foreach (float? value in new float?[] { null, 0, 1, -1, float.MinValue, float.MaxValue, float.Epsilon, float.NegativeInfinity, float.PositiveInfinity, float.NaN }) @@ -3381,7 +3369,6 @@ public static void ConvertNullableFloatToULongTest(bool useInterpreter) } [Theory, ClassData(typeof(CompilationTypes))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/51346", TestRuntimes.CoreCLR)] public static void ConvertNullableFloatToNullableULongTest(bool useInterpreter) { foreach (float? value in new float?[] { null, 0, 1, -1, float.MinValue, float.MaxValue, float.Epsilon, float.NegativeInfinity, float.PositiveInfinity, float.NaN }) diff --git a/src/tests/JIT/Methodical/Overflow/FloatOvfToInt2.cs b/src/tests/JIT/Methodical/Overflow/FloatOvfToInt2.cs index dfd292b755bec..acff1809714c4 100644 --- a/src/tests/JIT/Methodical/Overflow/FloatOvfToInt2.cs +++ b/src/tests/JIT/Methodical/Overflow/FloatOvfToInt2.cs @@ -6,6 +6,9 @@ internal class FloatOvfToInt { + [MethodImpl(MethodImplOptions.NoInlining)] + public static bool BreakUpFlow() => false; + [MethodImpl(MethodImplOptions.NoInlining)] public static long FloatToLong(float f) { @@ -228,6 +231,64 @@ public static int TestValuesFloatLong() return 100; } + public static int TestValuesFloatLongVN() + { + float bigf = 100000000000000000000000000000.0f; + + if (BreakUpFlow()) + return 1000; + + if (FloatToLong(bigf) != FloatToLongInline(bigf)) return 401; + if (FloatToUlong(bigf) != FloatToUlongInline(bigf)) return 402; + if (FloatToLong(-bigf) != FloatToLongInline(-bigf)) return 403; + if (FloatToUlong(-bigf) != FloatToUlongInline(-bigf)) return 404; + + bigf = 987654321001234567899876543210.0f; + + if (BreakUpFlow()) + return 1000; + + if (FloatToLong(bigf) != FloatToLongInline(bigf)) return 401; + if (FloatToUlong(bigf) != FloatToUlongInline(bigf)) return 402; + if (FloatToLong(-bigf) != FloatToLongInline(-bigf)) return 403; + if (FloatToUlong(-bigf) != FloatToUlongInline(-bigf)) return 404; + + bigf = 254783961024896571038054632179.0f; + + if (BreakUpFlow()) + return 1000; + + if (FloatToLong(bigf) != FloatToLongInline(bigf)) return 401; + if (FloatToUlong(bigf) != FloatToUlongInline(bigf)) return 402; + if (FloatToLong(-bigf) != FloatToLongInline(-bigf)) return 403; + if (FloatToUlong(-bigf) != FloatToUlongInline(-bigf)) return 404; + + return 100; + } + + public static int TestValuesFloatLongImport() + { + float bigf = 100000000000000000000000000000.0f; + if (FloatToLong(bigf) != FloatToLongInline(100000000000000000000000000000.0f)) return 501; + if (FloatToUlong(bigf) != FloatToUlongInline(100000000000000000000000000000.0f)) return 502; + if (FloatToLong(-bigf) != FloatToLongInline(-100000000000000000000000000000.0f)) return 503; + if (FloatToUlong(-bigf) != FloatToUlongInline(-100000000000000000000000000000.0f)) return 504; + + bigf = 987654321001234567899876543210.0f; + if (FloatToLong(bigf) != FloatToLongInline(987654321001234567899876543210.0f)) return 501; + if (FloatToUlong(bigf) != FloatToUlongInline(987654321001234567899876543210.0f)) return 502; + if (FloatToLong(-bigf) != FloatToLongInline(-987654321001234567899876543210.0f)) return 503; + if (FloatToUlong(-bigf) != FloatToUlongInline(-987654321001234567899876543210.0f)) return 504; + + bigf = 254783961024896571038054632179.0f; + if (FloatToLong(bigf) != FloatToLongInline(254783961024896571038054632179.0f)) return 501; + if (FloatToUlong(bigf) != FloatToUlongInline(254783961024896571038054632179.0f)) return 502; + if (FloatToLong(-bigf) != FloatToLongInline(-254783961024896571038054632179.0f)) return 503; + if (FloatToUlong(-bigf) != FloatToUlongInline(-254783961024896571038054632179.0f)) return 504; + + return 100; + } + public static int TestValuesFloatInt() { float bigf = 100000000000000000000000000000.0f; @@ -251,6 +312,64 @@ public static int TestValuesFloatInt() return 100; } + public static int TestValuesFloatIntVN() + { + float bigf = 100000000000000000000000000000.0f; + + if (BreakUpFlow()) + return 1000; + + if (FloatToInt(bigf) != FloatToIntInline(bigf)) return 411; + if (FloatToUint(bigf) != FloatToUintInline(bigf)) return 412; + if (FloatToInt(-bigf) != FloatToIntInline(-bigf)) return 413; + if (FloatToUint(-bigf) != FloatToUintInline(-bigf)) return 414; + + bigf = 987654321001234567899876543210.0f; + + if (BreakUpFlow()) + return 1000; + + if (FloatToInt(bigf) != FloatToIntInline(bigf)) return 411; + if (FloatToUint(bigf) != FloatToUintInline(bigf)) return 412; + if (FloatToInt(-bigf) != FloatToIntInline(-bigf)) return 413; + if (FloatToUint(-bigf) != FloatToUintInline(-bigf)) return 414; + + bigf = 254783961024896571038054632179.0f; + + if (BreakUpFlow()) + return 1000; + + if (FloatToInt(bigf) != FloatToIntInline(bigf)) return 411; + if (FloatToUint(bigf) != FloatToUintInline(bigf)) return 412; + if (FloatToInt(-bigf) != FloatToIntInline(-bigf)) return 413; + if (FloatToUint(-bigf) != FloatToUintInline(-bigf)) return 414; + + return 100; + } + + public static int TestValuesFloatIntImport() + { + float bigf = 100000000000000000000000000000.0f; + if (FloatToInt(bigf) != FloatToIntInline(100000000000000000000000000000.0f)) return 511; + if (FloatToUint(bigf) != FloatToUintInline(100000000000000000000000000000.0f)) return 512; + if (FloatToInt(-bigf) != FloatToIntInline(-100000000000000000000000000000.0f)) return 513; + if (FloatToUint(-bigf) != FloatToUintInline(-100000000000000000000000000000.0f)) return 514; + + bigf = 987654321001234567899876543210.0f; + if (FloatToInt(bigf) != FloatToIntInline(987654321001234567899876543210.0f)) return 511; + if (FloatToUint(bigf) != FloatToUintInline(987654321001234567899876543210.0f)) return 512; + if (FloatToInt(-bigf) != FloatToIntInline(-987654321001234567899876543210.0f)) return 513; + if (FloatToUint(-bigf) != FloatToUintInline(-987654321001234567899876543210.0f)) return 514; + + bigf = 254783961024896571038054632179.0f; + if (FloatToInt(bigf) != FloatToIntInline(254783961024896571038054632179.0f)) return 511; + if (FloatToUint(bigf) != FloatToUintInline(254783961024896571038054632179.0f)) return 512; + if (FloatToInt(-bigf) != FloatToIntInline(-254783961024896571038054632179.0f)) return 513; + if (FloatToUint(-bigf) != FloatToUintInline(-254783961024896571038054632179.0f)) return 514; + + return 100; + } + public static int TestValuesFloatShort() { float bigf = 100000000000000000000000000000.0f; @@ -274,6 +393,64 @@ public static int TestValuesFloatShort() return 100; } + public static int TestValuesFloatShortVN() + { + float bigf = 100000000000000000000000000000.0f; + + if (BreakUpFlow()) + return 1000; + + if (FloatToShort(bigf) != FloatToShortInline(bigf)) return 421; + if (FloatToUshort(bigf) != FloatToUshortInline(bigf)) return 422; + if (FloatToShort(-bigf) != FloatToShortInline(-bigf)) return 423; + if (FloatToUshort(-bigf) != FloatToUshortInline(-bigf)) return 424; + + bigf = 987654321001234567899876543210.0f; + + if (BreakUpFlow()) + return 1000; + + if (FloatToShort(bigf) != FloatToShortInline(bigf)) return 421; + if (FloatToUshort(bigf) != FloatToUshortInline(bigf)) return 422; + if (FloatToShort(-bigf) != FloatToShortInline(-bigf)) return 423; + if (FloatToUshort(-bigf) != FloatToUshortInline(-bigf)) return 424; + + bigf = 254783961024896571038054632179.0f; + + if (BreakUpFlow()) + return 1000; + + if (FloatToShort(bigf) != FloatToShortInline(bigf)) return 421; + if (FloatToUshort(bigf) != FloatToUshortInline(bigf)) return 422; + if (FloatToShort(-bigf) != FloatToShortInline(-bigf)) return 423; + if (FloatToUshort(-bigf) != FloatToUshortInline(-bigf)) return 424; + + return 100; + } + + public static int TestValuesFloatShortImport() + { + float bigf = 100000000000000000000000000000.0f; + if (FloatToShort(bigf) != FloatToShortInline(100000000000000000000000000000.0f)) return 521; + if (FloatToUshort(bigf) != FloatToUshortInline(100000000000000000000000000000.0f)) return 522; + if (FloatToShort(-bigf) != FloatToShortInline(-100000000000000000000000000000.0f)) return 523; + if (FloatToUshort(-bigf) != FloatToUshortInline(-100000000000000000000000000000.0f)) return 524; + + bigf = 987654321001234567899876543210.0f; + if (FloatToShort(bigf) != FloatToShortInline(987654321001234567899876543210.0f)) return 521; + if (FloatToUshort(bigf) != FloatToUshortInline(987654321001234567899876543210.0f)) return 522; + if (FloatToShort(-bigf) != FloatToShortInline(-987654321001234567899876543210.0f)) return 523; + if (FloatToUshort(-bigf) != FloatToUshortInline(-987654321001234567899876543210.0f)) return 524; + + bigf = 254783961024896571038054632179.0f; + if (FloatToShort(bigf) != FloatToShortInline(254783961024896571038054632179.0f)) return 521; + if (FloatToUshort(bigf) != FloatToUshortInline(254783961024896571038054632179.0f)) return 522; + if (FloatToShort(-bigf) != FloatToShortInline(-254783961024896571038054632179.0f)) return 523; + if (FloatToUshort(-bigf) != FloatToUshortInline(-254783961024896571038054632179.0f)) return 524; + + return 100; + } + public static int TestValuesFloatByte() { float bigf = 100000000000000000000000000000.0f; @@ -297,21 +474,91 @@ public static int TestValuesFloatByte() return 100; } + public static int TestValuesFloatByteVN() + { + float bigf = 100000000000000000000000000000.0f; + + if (BreakUpFlow()) + return 1000; + + if (FloatToSbyte(bigf) != FloatToSbyteInline(bigf)) return 441; + if (FloatToByte(bigf) != FloatToByteInline(bigf)) return 442; + if (FloatToSbyte(-bigf) != FloatToSbyteInline(-bigf)) return 443; + if (FloatToByte(-bigf) != FloatToByteInline(-bigf)) return 444; + + bigf = 987654321001234567899876543210.0f; + + if (BreakUpFlow()) + return 1000; + + if (FloatToSbyte(bigf) != FloatToSbyteInline(bigf)) return 441; + if (FloatToByte(bigf) != FloatToByteInline(bigf)) return 442; + if (FloatToSbyte(-bigf) != FloatToSbyteInline(-bigf)) return 443; + if (FloatToByte(-bigf) != FloatToByteInline(-bigf)) return 444; + + bigf = 254783961024896571038054632179.0f; + + if (BreakUpFlow()) + return 1000; + + if (FloatToSbyte(bigf) != FloatToSbyteInline(bigf)) return 441; + if (FloatToByte(bigf) != FloatToByteInline(bigf)) return 442; + if (FloatToSbyte(-bigf) != FloatToSbyteInline(-bigf)) return 443; + if (FloatToByte(-bigf) != FloatToByteInline(-bigf)) return 444; + + return 100; + } + + public static int TestValuesFloatByteImport() + { + float bigf = 100000000000000000000000000000.0f; + if (FloatToSbyte(bigf) != FloatToSbyteInline(100000000000000000000000000000.0f)) return 541; + if (FloatToByte(bigf) != FloatToByteInline(100000000000000000000000000000.0f)) return 542; + if (FloatToSbyte(-bigf) != FloatToSbyteInline(-100000000000000000000000000000.0f)) return 543; + if (FloatToByte(-bigf) != FloatToByteInline(-100000000000000000000000000000.0f)) return 544; + + bigf = 987654321001234567899876543210.0f; + if (FloatToSbyte(bigf) != FloatToSbyteInline(987654321001234567899876543210.0f)) return 541; + if (FloatToByte(bigf) != FloatToByteInline(987654321001234567899876543210.0f)) return 542; + if (FloatToSbyte(-bigf) != FloatToSbyteInline(-987654321001234567899876543210.0f)) return 543; + if (FloatToByte(-bigf) != FloatToByteInline(-987654321001234567899876543210.0f)) return 544; + + bigf = 254783961024896571038054632179.0f; + if (FloatToSbyte(bigf) != FloatToSbyteInline(254783961024896571038054632179.0f)) return 541; + if (FloatToByte(bigf) != FloatToByteInline(254783961024896571038054632179.0f)) return 542; + if (FloatToSbyte(-bigf) != FloatToSbyteInline(-254783961024896571038054632179.0f)) return 543; + if (FloatToByte(-bigf) != FloatToByteInline(-254783961024896571038054632179.0f)) return 544; + + return 100; + } + public static int TestValuesDoubleLong() { double bigd = 100000000000000000000000000000.0; + + if (BreakUpFlow()) + return 1000; + if (DoubleToLong(bigd) != DoubleToLongInline(bigd)) return 201; if (DoubleToUlong(bigd) != DoubleToUlongInline(bigd)) return 202; if (DoubleToLong(-bigd) != DoubleToLongInline(-bigd)) return 203; if (DoubleToUlong(-bigd) != DoubleToUlongInline(-bigd)) return 204; bigd = 987654321001234567899876543210.0; + + if (BreakUpFlow()) + return 1000; + if (DoubleToLong(bigd) != DoubleToLongInline(bigd)) return 201; if (DoubleToUlong(bigd) != DoubleToUlongInline(bigd)) return 202; if (DoubleToLong(-bigd) != DoubleToLongInline(-bigd)) return 203; if (DoubleToUlong(-bigd) != DoubleToUlongInline(-bigd)) return 204; bigd = 254783961024896571038054632179.0; + + if (BreakUpFlow()) + return 1000; + if (DoubleToLong(bigd) != DoubleToLongInline(bigd)) return 201; if (DoubleToUlong(bigd) != DoubleToUlongInline(bigd)) return 202; if (DoubleToLong(-bigd) != DoubleToLongInline(-bigd)) return 203; @@ -320,6 +567,52 @@ public static int TestValuesDoubleLong() return 100; } + public static int TestValuesDoubleLongVN() + { + double bigd = 100000000000000000000000000000.0; + if (DoubleToLong(bigd) != DoubleToLongInline(bigd)) return 301; + if (DoubleToUlong(bigd) != DoubleToUlongInline(bigd)) return 302; + if (DoubleToLong(-bigd) != DoubleToLongInline(-bigd)) return 303; + if (DoubleToUlong(-bigd) != DoubleToUlongInline(-bigd)) return 304; + + bigd = 987654321001234567899876543210.0; + if (DoubleToLong(bigd) != DoubleToLongInline(bigd)) return 301; + if (DoubleToUlong(bigd) != DoubleToUlongInline(bigd)) return 302; + if (DoubleToLong(-bigd) != DoubleToLongInline(-bigd)) return 303; + if (DoubleToUlong(-bigd) != DoubleToUlongInline(-bigd)) return 304; + + bigd = 254783961024896571038054632179.0; + if (DoubleToLong(bigd) != DoubleToLongInline(bigd)) return 301; + if (DoubleToUlong(bigd) != DoubleToUlongInline(bigd)) return 302; + if (DoubleToLong(-bigd) != DoubleToLongInline(-bigd)) return 303; + if (DoubleToUlong(-bigd) != DoubleToUlongInline(-bigd)) return 304; + + return 100; + } + + public static int TestValuesDoubleLongImport() + { + double bigd = 100000000000000000000000000000.0; + if (DoubleToLong(bigd) != DoubleToLongInline(100000000000000000000000000000.0)) return 601; + if (DoubleToUlong(bigd) != DoubleToUlongInline(100000000000000000000000000000.0)) return 602; + if (DoubleToLong(-bigd) != DoubleToLongInline(-100000000000000000000000000000.0)) return 603; + if (DoubleToUlong(-bigd) != DoubleToUlongInline(-100000000000000000000000000000.0)) return 604; + + bigd = 987654321001234567899876543210.0; + if (DoubleToLong(bigd) != DoubleToLongInline(987654321001234567899876543210.0)) return 601; + if (DoubleToUlong(bigd) != DoubleToUlongInline(987654321001234567899876543210.0)) return 602; + if (DoubleToLong(-bigd) != DoubleToLongInline(-987654321001234567899876543210.0)) return 603; + if (DoubleToUlong(-bigd) != DoubleToUlongInline(-987654321001234567899876543210.0)) return 604; + + bigd = 254783961024896571038054632179.0; + if (DoubleToLong(bigd) != DoubleToLongInline(254783961024896571038054632179.0)) return 601; + if (DoubleToUlong(bigd) != DoubleToUlongInline(254783961024896571038054632179.0)) return 602; + if (DoubleToLong(-bigd) != DoubleToLongInline(-254783961024896571038054632179.0)) return 603; + if (DoubleToUlong(-bigd) != DoubleToUlongInline(-254783961024896571038054632179.0)) return 604; + + return 100; + } + public static int TestValuesDoubleInt() { double bigd = 100000000000000000000000000000.0; @@ -343,6 +636,64 @@ public static int TestValuesDoubleInt() return 100; } + public static int TestValuesDoubleIntVN() + { + double bigd = 100000000000000000000000000000.0; + + if (BreakUpFlow()) + return 1000; + + if (DoubleToInt(bigd) != DoubleToIntInline(bigd)) return 311; + if (DoubleToUint(bigd) != DoubleToUintInline(bigd)) return 312; + if (DoubleToInt(-bigd) != DoubleToIntInline(-bigd)) return 313; + if (DoubleToUint(-bigd) != DoubleToUintInline(-bigd)) return 314; + + bigd = 987654321001234567899876543210.0; + + if (BreakUpFlow()) + return 1000; + + if (DoubleToInt(bigd) != DoubleToIntInline(bigd)) return 311; + if (DoubleToUint(bigd) != DoubleToUintInline(bigd)) return 312; + if (DoubleToInt(-bigd) != DoubleToIntInline(-bigd)) return 313; + if (DoubleToUint(-bigd) != DoubleToUintInline(-bigd)) return 314; + + bigd = 254783961024896571038054632179.0; + + if (BreakUpFlow()) + return 1000; + + if (DoubleToInt(bigd) != DoubleToIntInline(bigd)) return 311; + if (DoubleToUint(bigd) != DoubleToUintInline(bigd)) return 312; + if (DoubleToInt(-bigd) != DoubleToIntInline(-bigd)) return 313; + if (DoubleToUint(-bigd) != DoubleToUintInline(-bigd)) return 314; + + return 100; + } + + public static int TestValuesDoubleIntImport() + { + double bigd = 100000000000000000000000000000.0; + if (DoubleToInt(bigd) != DoubleToIntInline(100000000000000000000000000000.0)) return 611; + if (DoubleToUint(bigd) != DoubleToUintInline(100000000000000000000000000000.0)) return 612; + if (DoubleToInt(-bigd) != DoubleToIntInline(-100000000000000000000000000000.0)) return 613; + if (DoubleToUint(-bigd) != DoubleToUintInline(-100000000000000000000000000000.0)) return 614; + + bigd = 987654321001234567899876543210.0; + if (DoubleToInt(bigd) != DoubleToIntInline(987654321001234567899876543210.0)) return 611; + if (DoubleToUint(bigd) != DoubleToUintInline(987654321001234567899876543210.0)) return 612; + if (DoubleToInt(-bigd) != DoubleToIntInline(-987654321001234567899876543210.0)) return 613; + if (DoubleToUint(-bigd) != DoubleToUintInline(-987654321001234567899876543210.0)) return 614; + + bigd = 254783961024896571038054632179.0; + if (DoubleToInt(bigd) != DoubleToIntInline(254783961024896571038054632179.0)) return 611; + if (DoubleToUint(bigd) != DoubleToUintInline(254783961024896571038054632179.0)) return 612; + if (DoubleToInt(-bigd) != DoubleToIntInline(-254783961024896571038054632179.0)) return 613; + if (DoubleToUint(-bigd) != DoubleToUintInline(-254783961024896571038054632179.0)) return 614; + + return 100; + } + public static int TestValuesDoubleShort() { double bigd = 100000000000000000000000000000.0; @@ -366,6 +717,64 @@ public static int TestValuesDoubleShort() return 100; } + public static int TestValuesDoubleShortVN() + { + double bigd = 100000000000000000000000000000.0; + + if (BreakUpFlow()) + return 1000; + + if (DoubleToShort(bigd) != DoubleToShortInline(bigd)) return 321; + if (DoubleToUshort(bigd) != DoubleToUshortInline(bigd)) return 322; + if (DoubleToShort(-bigd) != DoubleToShortInline(-bigd)) return 323; + if (DoubleToUshort(-bigd) != DoubleToUshortInline(-bigd)) return 324; + + bigd = 987654321001234567899876543210.0; + + if (BreakUpFlow()) + return 1000; + + if (DoubleToShort(bigd) != DoubleToShortInline(bigd)) return 321; + if (DoubleToUshort(bigd) != DoubleToUshortInline(bigd)) return 322; + if (DoubleToShort(-bigd) != DoubleToShortInline(-bigd)) return 323; + if (DoubleToUshort(-bigd) != DoubleToUshortInline(-bigd)) return 324; + + bigd = 254783961024896571038054632179.0; + + if (BreakUpFlow()) + return 1000; + + if (DoubleToShort(bigd) != DoubleToShortInline(bigd)) return 321; + if (DoubleToUshort(bigd) != DoubleToUshortInline(bigd)) return 322; + if (DoubleToShort(-bigd) != DoubleToShortInline(-bigd)) return 323; + if (DoubleToUshort(-bigd) != DoubleToUshortInline(-bigd)) return 324; + + return 100; + } + + public static int TestValuesDoubleShortImport() + { + double bigd = 100000000000000000000000000000.0; + if (DoubleToShort(bigd) != DoubleToShortInline(100000000000000000000000000000.0)) return 621; + if (DoubleToUshort(bigd) != DoubleToUshortInline(100000000000000000000000000000.0)) return 622; + if (DoubleToShort(-bigd) != DoubleToShortInline(-100000000000000000000000000000.0)) return 623; + if (DoubleToUshort(-bigd) != DoubleToUshortInline(-bigd)) return 624; + + bigd = 987654321001234567899876543210.0; + if (DoubleToShort(bigd) != DoubleToShortInline(987654321001234567899876543210.0)) return 621; + if (DoubleToUshort(bigd) != DoubleToUshortInline(987654321001234567899876543210.0)) return 622; + if (DoubleToShort(-bigd) != DoubleToShortInline(-987654321001234567899876543210.0)) return 623; + if (DoubleToUshort(-bigd) != DoubleToUshortInline(-987654321001234567899876543210.0)) return 624; + + bigd = 254783961024896571038054632179.0; + if (DoubleToShort(bigd) != DoubleToShortInline(254783961024896571038054632179.0)) return 621; + if (DoubleToUshort(bigd) != DoubleToUshortInline(254783961024896571038054632179.0)) return 622; + if (DoubleToShort(-bigd) != DoubleToShortInline(-254783961024896571038054632179.0)) return 623; + if (DoubleToUshort(-bigd) != DoubleToUshortInline(-254783961024896571038054632179.0)) return 624; + + return 100; + } + public static int TestValuesDoubleByte() { double bigd = 100000000000000000000000000000.0; @@ -389,17 +798,91 @@ public static int TestValuesDoubleByte() return 100; } + public static int TestValuesDoubleByteVN() + { + double bigd = 100000000000000000000000000000.0; + + if (BreakUpFlow()) + return 1000; + + if (DoubleToSbyte(bigd) != DoubleToSbyteInline(bigd)) return 341; + if (DoubleToByte(bigd) != DoubleToByteInline(bigd)) return 342; + if (DoubleToSbyte(-bigd) != DoubleToSbyteInline(-bigd)) return 343; + if (DoubleToByte(-bigd) != DoubleToByteInline(-bigd)) return 344; + + bigd = 987654321001234567899876543210.0; + + if (BreakUpFlow()) + return 1000; + + if (DoubleToSbyte(bigd) != DoubleToSbyteInline(bigd)) return 341; + if (DoubleToByte(bigd) != DoubleToByteInline(bigd)) return 342; + if (DoubleToSbyte(-bigd) != DoubleToSbyteInline(-bigd)) return 343; + if (DoubleToByte(-bigd) != DoubleToByteInline(-bigd)) return 344; + + bigd = 254783961024896571038054632179.0; + + if (BreakUpFlow()) + return 1000; + + if (DoubleToSbyte(bigd) != DoubleToSbyteInline(bigd)) return 341; + if (DoubleToByte(bigd) != DoubleToByteInline(bigd)) return 342; + if (DoubleToSbyte(-bigd) != DoubleToSbyteInline(-bigd)) return 343; + if (DoubleToByte(-bigd) != DoubleToByteInline(-bigd)) return 344; + + return 100; + } + + public static int TestValuesDoubleByteImport() + { + double bigd = 100000000000000000000000000000.0; + if (DoubleToSbyte(bigd) != DoubleToSbyteInline(100000000000000000000000000000.0)) return 641; + if (DoubleToByte(bigd) != DoubleToByteInline(100000000000000000000000000000.0)) return 642; + if (DoubleToSbyte(-bigd) != DoubleToSbyteInline(-100000000000000000000000000000.0)) return 643; + if (DoubleToByte(-bigd) != DoubleToByteInline(-100000000000000000000000000000.0)) return 644; + + bigd = 987654321001234567899876543210.0; + if (DoubleToSbyte(bigd) != DoubleToSbyteInline(987654321001234567899876543210.0)) return 641; + if (DoubleToByte(bigd) != DoubleToByteInline(987654321001234567899876543210.0)) return 642; + if (DoubleToSbyte(-bigd) != DoubleToSbyteInline(-987654321001234567899876543210.0)) return 643; + if (DoubleToByte(-bigd) != DoubleToByteInline(-987654321001234567899876543210.0)) return 644; + + bigd = 254783961024896571038054632179.0; + if (DoubleToSbyte(bigd) != DoubleToSbyteInline(987654321001234567899876543210.0)) return 641; + if (DoubleToByte(bigd) != DoubleToByteInline(987654321001234567899876543210.0)) return 642; + if (DoubleToSbyte(-bigd) != DoubleToSbyteInline(-987654321001234567899876543210.0)) return 643; + if (DoubleToByte(-bigd) != DoubleToByteInline(-987654321001234567899876543210.0)) return 644; + + return 100; + } + public static int TestValues() { int res = TestValuesFloatLong(); if (res != 100) return res; + res = TestValuesFloatLongVN(); if (res != 100) return res; + res = TestValuesFloatLongImport(); if (res != 100) return res; res = TestValuesFloatInt(); if (res != 100) return res; + res = TestValuesFloatIntVN(); if (res != 100) return res; + res = TestValuesFloatIntImport(); if (res != 100) return res; res = TestValuesFloatShort(); if (res != 100) return res; + res = TestValuesFloatShortImport(); if (res != 100) return res; + res = TestValuesFloatShortVN(); if (res != 100) return res; res = TestValuesFloatByte(); if (res != 100) return res; + res = TestValuesFloatByteImport(); if (res != 100) return res; + res = TestValuesFloatByteVN(); if (res != 100) return res; res = TestValuesDoubleLong(); if (res != 100) return res; + res = TestValuesDoubleLongVN(); if (res != 100) return res; + res = TestValuesDoubleLongImport(); if (res != 100) return res; res = TestValuesDoubleInt(); if (res != 100) return res; + res = TestValuesDoubleIntVN(); if (res != 100) return res; + res = TestValuesDoubleIntImport(); if (res != 100) return res; res = TestValuesDoubleShort(); if (res != 100) return res; + res = TestValuesDoubleShortVN(); if (res != 100) return res; + res = TestValuesDoubleShortImport(); if (res != 100) return res; res = TestValuesDoubleByte(); if (res != 100) return res; + res = TestValuesDoubleByteVN(); if (res != 100) return res; + res = TestValuesDoubleByteImport(); if (res != 100) return res; return res; } diff --git a/src/tests/issues.targets b/src/tests/issues.targets index f94900a742146..169d2c0b213e1 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -1026,6 +1026,18 @@ Mono does not define out of range fp to int conversions + + https://github.com/dotnet/runtime/issues/51323 + + + https://github.com/dotnet/runtime/issues/51323 + + + https://github.com/dotnet/runtime/issues/51323 + + + https://github.com/dotnet/runtime/issues/51323 + https://github.com/dotnet/runtime/issues/48190