[mono] Fix conversions from float to integer (#57048)
authorVlad Brezae <brezaevlad@gmail.com>
Mon, 9 Aug 2021 22:00:57 +0000 (01:00 +0300)
committerGitHub <noreply@github.com>
Mon, 9 Aug 2021 22:00:57 +0000 (01:00 +0300)
* [interp] Fix conversions from float to integer

.un prefix is ignored for these conversions

* [mini] Fix conversions from float to integer

.un prefix is ignored for these conversions

* Re-enable test

src/mono/mono/mini/interp/interp.c
src/mono/mono/mini/interp/mintops.def
src/mono/mono/mini/interp/transform.c
src/mono/mono/mini/method-to-ir.c
src/tests/issues.targets

index eff4a4e..0e2b020 100644 (file)
@@ -5445,14 +5445,6 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK;
                        ip += 4;
                        MINT_IN_BREAK;
                }
-               MINT_IN_CASE(MINT_CONV_OVF_I4_UN_R8) {
-                       double val = LOCAL_VAR (ip [2], double);
-                       if (val < 0 || val > G_MAXINT32)
-                               THROW_EX (mono_get_exception_overflow (), ip);
-                       LOCAL_VAR (ip [1], gint32) = (gint32)val;
-                       ip += 3;
-                       MINT_IN_BREAK;
-               }
                MINT_IN_CASE(MINT_CONV_OVF_U8_I4) {
                        gint32 val = LOCAL_VAR (ip [2], gint32);
                        if (val < 0)
@@ -5493,22 +5485,6 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK;
                        ip += 3;
                        MINT_IN_BREAK;
                }
-               MINT_IN_CASE(MINT_CONV_OVF_I8_UN_R8) {
-                       double val = LOCAL_VAR (ip [2], double);
-                       if (val < 0 || mono_isnan (val) || mono_trunc (val) != (gint64)val)
-                               THROW_EX (mono_get_exception_overflow (), ip);
-                       LOCAL_VAR (ip [1], gint64) = (gint64)val;
-                       ip += 3;
-                       MINT_IN_BREAK;
-               }
-               MINT_IN_CASE(MINT_CONV_OVF_I8_UN_R4) {
-                       float val = LOCAL_VAR (ip [2], float);
-                       if (val < 0 || mono_isnan (val) || mono_trunc (val) != (gint64)val)
-                               THROW_EX (mono_get_exception_overflow (), ip);
-                       LOCAL_VAR (ip [1], gint64) = (gint64)val;
-                       ip += 3;
-                       MINT_IN_BREAK;
-               }
                MINT_IN_CASE(MINT_CONV_OVF_I8_R4) {
                        float val = LOCAL_VAR (ip [2], float);
                        if (mono_isnan (val) || mono_trunc (val) != (gint64)val)
@@ -5917,21 +5893,6 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK;
                        ip += 3;
                        MINT_IN_BREAK;
                }
-               MINT_IN_CASE(MINT_CONV_OVF_I2_UN_R4) {
-                       float val = LOCAL_VAR (ip [2], float);
-                       if (val < 0 || val > G_MAXINT16 || isnan (val))
-                               THROW_EX (mono_get_exception_overflow (), ip);
-                       LOCAL_VAR (ip [1], gint32) = (gint16) val;
-                       ip += 3;
-                       MINT_IN_BREAK;
-               }
-               MINT_IN_CASE(MINT_CONV_OVF_I2_UN_R8) {
-                       double val = LOCAL_VAR (ip [2], double);
-                       if (val < 0 || val > G_MAXINT16 || isnan (val))
-                               THROW_EX (mono_get_exception_overflow (), ip);
-                       LOCAL_VAR (ip [1], gint32) = (gint16) val;
-                       MINT_IN_BREAK;
-               }
                MINT_IN_CASE(MINT_CONV_OVF_U2_I4) {
                        gint32 val = LOCAL_VAR (ip [2], gint32);
                        if (val < 0 || val > G_MAXUINT16)
@@ -6012,22 +5973,6 @@ MINT_IN_CASE(MINT_BRTRUE_I8_SP) ZEROP_SP(gint64, !=); MINT_IN_BREAK;
                        ip += 3;
                        MINT_IN_BREAK;
                }
-               MINT_IN_CASE(MINT_CONV_OVF_I1_UN_R4) {
-                       float val = LOCAL_VAR (ip [2], float);
-                       if (val < 0 || val > G_MAXINT8 || isnan (val))
-                               THROW_EX (mono_get_exception_overflow (), ip);
-                       LOCAL_VAR (ip [1], gint32) = (gint8) val;
-                       ip += 3;
-                       MINT_IN_BREAK;
-               }
-               MINT_IN_CASE(MINT_CONV_OVF_I1_UN_R8) {
-                       double val = LOCAL_VAR (ip [2], double);
-                       if (val < 0 || val > G_MAXINT8 || isnan (val))
-                               THROW_EX (mono_get_exception_overflow (), ip);
-                       LOCAL_VAR (ip [1], gint32) = (gint8) val;
-                       ip += 3;
-                       MINT_IN_BREAK;
-               }
                MINT_IN_CASE(MINT_CONV_OVF_U1_I4) {
                        gint32 val = LOCAL_VAR (ip [2], gint32);
                        if (val < 0 || val > G_MAXUINT8)
index 0de8708..4ef8ee7 100644 (file)
@@ -583,8 +583,6 @@ OPDEF(MINT_CONV_OVF_I1_R8, "conv.ovf.i1.r8", 3, 1, 1, MintOpNoArgs)
 
 OPDEF(MINT_CONV_OVF_I1_U4, "conv.ovf.i1.u4", 3, 1, 1, MintOpNoArgs)
 OPDEF(MINT_CONV_OVF_I1_U8, "conv.ovf.i1.u8", 3, 1, 1, MintOpNoArgs)
-OPDEF(MINT_CONV_OVF_I1_UN_R4, "conv.ovf.i1.un.r4", 3, 1, 1, MintOpNoArgs)
-OPDEF(MINT_CONV_OVF_I1_UN_R8, "conv.ovf.i1.un.r8", 3, 1, 1, MintOpNoArgs)
 
 OPDEF(MINT_CONV_OVF_U1_I4, "conv.ovf.u1.i4", 3, 1, 1, MintOpNoArgs)
 OPDEF(MINT_CONV_OVF_U1_I8, "conv.ovf.u1.i8", 3, 1, 1, MintOpNoArgs)
@@ -598,8 +596,6 @@ OPDEF(MINT_CONV_OVF_I2_R8, "conv.ovf.i2.r8", 3, 1, 1, MintOpNoArgs)
 
 OPDEF(MINT_CONV_OVF_I2_U4, "conv.ovf.i2.u4", 3, 1, 1, MintOpNoArgs)
 OPDEF(MINT_CONV_OVF_I2_U8, "conv.ovf.i2.u8", 3, 1, 1, MintOpNoArgs)
-OPDEF(MINT_CONV_OVF_I2_UN_R4, "conv.ovf.i2.un.r4", 3, 1, 1, MintOpNoArgs)
-OPDEF(MINT_CONV_OVF_I2_UN_R8, "conv.ovf.i2.un.r8", 3, 1, 1, MintOpNoArgs)
 
 OPDEF(MINT_CONV_OVF_U2_I4, "conv.ovf.u2.i4", 3, 1, 1, MintOpNoArgs)
 OPDEF(MINT_CONV_OVF_U2_I8, "conv.ovf.u2.i8", 3, 1, 1, MintOpNoArgs)
@@ -612,8 +608,6 @@ OPDEF(MINT_CONV_OVF_I4_U8, "conv.ovf.i4.u8", 3, 1, 1, MintOpNoArgs)
 OPDEF(MINT_CONV_OVF_I4_R4, "conv.ovf.i4.r4", 3, 1, 1, MintOpNoArgs)
 OPDEF(MINT_CONV_OVF_I4_R8, "conv.ovf.i4.r8", 3, 1, 1, MintOpNoArgs)
 
-OPDEF(MINT_CONV_OVF_I4_UN_R8, "conv.ovf.i4.un.r8", 3, 1, 1, MintOpNoArgs)
-
 OPDEF(MINT_CONV_OVF_U4_I4, "conv.ovf.u4.i4", 3, 1, 1, MintOpNoArgs)
 OPDEF(MINT_CONV_OVF_U4_I8, "conv.ovf.u4.i8", 3, 1, 1, MintOpNoArgs)
 OPDEF(MINT_CONV_OVF_U4_R4, "conv.ovf.u4.r4", 3, 1, 1, MintOpNoArgs)
@@ -623,9 +617,6 @@ OPDEF(MINT_CONV_OVF_I8_U8, "conv.ovf.i8.u8", 3, 1, 1, MintOpNoArgs)
 OPDEF(MINT_CONV_OVF_I8_R4, "conv.ovf.i8.r4", 3, 1, 1, MintOpNoArgs)
 OPDEF(MINT_CONV_OVF_I8_R8, "conv.ovf.i8.r8", 3, 1, 1, MintOpNoArgs)
 
-OPDEF(MINT_CONV_OVF_I8_UN_R8, "conv.ovf.i8.un.r8", 3, 1, 1, MintOpNoArgs)
-OPDEF(MINT_CONV_OVF_I8_UN_R4, "conv.ovf.i8.un.r4", 3, 1, 1, MintOpNoArgs)
-
 OPDEF(MINT_CONV_OVF_U8_I4, "conv.ovf.u8.i4", 3, 1, 1, MintOpNoArgs)
 OPDEF(MINT_CONV_OVF_U8_I8, "conv.ovf.u8.i8", 3, 1, 1, MintOpNoArgs)
 OPDEF(MINT_CONV_OVF_U8_R4, "conv.ovf.u8.r4", 3, 1, 1, MintOpNoArgs)
index c677122..23570b4 100644 (file)
@@ -6141,24 +6141,44 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
                }
 #if SIZEOF_VOID_P == 8
                case CEE_CONV_OVF_I_UN:
-               case CEE_CONV_OVF_U_UN:
 #endif
                case CEE_CONV_OVF_I8_UN:
-               case CEE_CONV_OVF_U8_UN:
                        CHECK_STACK (td, 1);
                        switch (td->sp [-1].type) {
+                       case STACK_TYPE_R4:
+                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I8, MINT_CONV_OVF_I8_R4);
+                               break;
                        case STACK_TYPE_R8:
-                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I8, MINT_CONV_OVF_I8_UN_R8);
+                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I8, MINT_CONV_OVF_I8_R8);
+                               break;
+                       case STACK_TYPE_I4:
+                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I8, MINT_CONV_I8_U4);
                                break;
                        case STACK_TYPE_I8:
-                               if (*td->ip == CEE_CONV_OVF_I8_UN || *td->ip == CEE_CONV_OVF_I_UN)
-                                       interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I8, MINT_CONV_OVF_I8_U8);
+                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I8, MINT_CONV_OVF_I8_U8);
+                               break;
+                       default:
+                               g_assert_not_reached ();
+                               break;
+                       }
+                       ++td->ip;
+                       break;
+#if SIZEOF_VOID_P == 8
+               case CEE_CONV_OVF_U_UN:
+#endif
+               case CEE_CONV_OVF_U8_UN:
+                       CHECK_STACK (td, 1);
+                       switch (td->sp [-1].type) {
+                       case STACK_TYPE_R4:
+                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I8, MINT_CONV_OVF_U8_R4);
+                               break;
+                       case STACK_TYPE_R8:
+                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I8, MINT_CONV_OVF_U8_R8);
                                break;
                        case STACK_TYPE_I4:
                                interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I8, MINT_CONV_I8_U4);
                                break;
-                       case STACK_TYPE_R4:
-                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I8, MINT_CONV_OVF_I8_UN_R4);
+                       case STACK_TYPE_I8:
                                break;
                        default:
                                g_assert_not_reached ();
@@ -6515,10 +6535,10 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
                        CHECK_STACK (td, 1);
                        switch (td->sp [-1].type) {
                        case STACK_TYPE_R4:
-                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I4, is_un ? MINT_CONV_OVF_I1_UN_R4 : MINT_CONV_OVF_I1_R4);
+                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I4, MINT_CONV_OVF_I1_R4);
                                break;
                        case STACK_TYPE_R8:
-                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I4, is_un ? MINT_CONV_OVF_I1_UN_R8 : MINT_CONV_OVF_I1_R8);
+                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I4, MINT_CONV_OVF_I1_R8);
                                break;
                        case STACK_TYPE_I4:
                                interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I4, is_un ? MINT_CONV_OVF_I1_U4 : MINT_CONV_OVF_I1_I4);
@@ -6559,10 +6579,10 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
                        CHECK_STACK (td, 1);
                        switch (td->sp [-1].type) {
                        case STACK_TYPE_R4:
-                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I4, is_un ? MINT_CONV_OVF_I2_UN_R4 : MINT_CONV_OVF_I2_R4);
+                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I4, MINT_CONV_OVF_I2_R4);
                                break;
                        case STACK_TYPE_R8:
-                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I4, is_un ? MINT_CONV_OVF_I2_UN_R8 : MINT_CONV_OVF_I2_R8);
+                               interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I4, MINT_CONV_OVF_I2_R8);
                                break;
                        case STACK_TYPE_I4:
                                interp_add_conv (td, td->sp - 1, NULL, STACK_TYPE_I4, is_un ? MINT_CONV_OVF_I2_U4 : MINT_CONV_OVF_I2_I4);
index b28e16d..0e0ec07 100644 (file)
@@ -8493,7 +8493,16 @@ calli_end:
                        if (sp [-1]->type == STACK_R8 || sp [-1]->type == STACK_R4) {
                                /* floats are always signed, _UN has no effect */
                                ADD_UNOP (CEE_CONV_OVF_I8);
-                               ADD_UNOP (il_op);
+                               if (il_op == MONO_CEE_CONV_OVF_I1_UN)
+                                       ADD_UNOP (MONO_CEE_CONV_OVF_I1);
+                               else if (il_op == MONO_CEE_CONV_OVF_I2_UN)
+                                       ADD_UNOP (MONO_CEE_CONV_OVF_I2);
+                               else if (il_op == MONO_CEE_CONV_OVF_I4_UN)
+                                       ADD_UNOP (MONO_CEE_CONV_OVF_I4);
+                               else if (il_op == MONO_CEE_CONV_OVF_I8_UN)
+                                       ;
+                               else
+                                       ADD_UNOP (il_op);
                        } else {
                                ADD_UNOP (il_op);
                        }
index e01ee08..9d9040c 100644 (file)
         <ExcludeList Include = "$(XunitTestBinBase)/JIT/Directed/debugging/poison/**">
             <Issue>Tests coreclr JIT's debug poisoning of address taken variables</Issue>
         </ExcludeList>
-        <ExcludeList Include = "$(XunitTestBinBase)/JIT/IL_Conformance/TestConvertFromIntegral/**">
-            <Issue>https://github.com/dotnet/runtime/issues/56784</Issue>
-        </ExcludeList>
     </ItemGroup>
 
     <!-- Known failures for mono runtime on *all* architectures/operating systems in interpreter runtime mode -->