2008-06-13 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Fri, 13 Jun 2008 18:33:58 +0000 (18:33 -0000)
committerZoltan Varga <vargaz@gmail.com>
Fri, 13 Jun 2008 18:33:58 +0000 (18:33 -0000)
* inssel.brg: Remove the OP_MIN/OP_MAX rules. Fix a warning.

* mini.c (mini_get_inst_for_method): Remove the Min/Max intrinsics, they
do not work even for unsigned types. Fixes #400014.

* basic-math.cs: Add regression tests for unsigned Min/Max.

svn path=/trunk/mono/; revision=105786

mono/mini/ChangeLog
mono/mini/basic-math.cs
mono/mini/inssel.brg
mono/mini/mini.c

index 576db8559a37f5bb0701f2cbba77cd017568535f..213b93f74af8fc0e4c8e7f2f1c3573e210eeb8a5 100644 (file)
@@ -1,3 +1,12 @@
+2008-06-13  Zoltan Varga  <vargaz@gmail.com>
+
+       * inssel.brg: Remove the OP_MIN/OP_MAX rules. Fix a warning.
+
+       * mini.c (mini_get_inst_for_method): Remove the Min/Max intrinsics, they
+       do not work even for unsigned types. Fixes #400014.
+
+       * basic-math.cs: Add regression tests for unsigned Min/Max.
+
 2008-06-13  Mark Probst  <mark.probst@gmail.com>
 
        * mini.c: Added additional context_used argument to several
index c470c8f13333b82a2ffa89db2d6091a03a133e76..a1e5030abefc451ab484b6c05f13232e7870e383 100644 (file)
@@ -188,6 +188,29 @@ class Tests {
                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;
+               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;
+               }
+               return 0;
+       }
+
        public static int test_0_abs () {
                double d = -5.0;
 
index d48f635fc5c56e2a818c7a1c55462ea679cca682..5300b77aa826b722138ad0f257c7fa54b9fc989f 100644 (file)
@@ -1723,7 +1723,6 @@ stmt: CEE_MKREFANY (OP_GROUP (reg, OP_I8CONST), reg) {
 }
 
 stmt: OP_MKREFANY_REGS (OP_GROUP (reg, reg), OP_GROUP (reg, reg)) {
-       int class_reg = state->left->right->reg1;
        g_assert (!s->compile_aot);
        MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREP_MEMBASE_REG,
                        state->right->right->reg1, G_STRUCT_OFFSET (MonoTypedRef, type), state->left->left->reg1);
@@ -1733,28 +1732,6 @@ stmt: OP_MKREFANY_REGS (OP_GROUP (reg, reg), OP_GROUP (reg, reg)) {
                        state->right->right->reg1, G_STRUCT_OFFSET (MonoTypedRef, value), state->right->left->reg1);
 }
 
-reg: OP_MIN (reg, reg) "2" {
-       /* min (x,y) = y + (((x-y)>>31)&(x-y)); */
-       int diff = mono_regstate_next_int (s->rs);
-       int shifted = mono_regstate_next_int (s->rs);
-       int anded = mono_regstate_next_int (s->rs);
-       MONO_EMIT_NEW_BIALU (s, CEE_SUB, diff, state->left->reg1, state->right->reg1);
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, shifted, diff, (sizeof(void*)*8-1));
-       MONO_EMIT_NEW_BIALU (s, CEE_AND, anded, shifted, diff);
-       MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, anded, state->right->reg1);
-}
-
-reg: OP_MAX (reg, reg) "2" {
-       /* max (x,y) = x - (((x-y)>>31)&(x-y)); */
-       int diff = mono_regstate_next_int (s->rs);
-       int shifted = mono_regstate_next_int (s->rs);
-       int anded = mono_regstate_next_int (s->rs);
-       MONO_EMIT_NEW_BIALU (s, CEE_SUB, diff, state->left->reg1, state->right->reg1);
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, shifted, diff, (sizeof(void*)*8-1));
-       MONO_EMIT_NEW_BIALU (s, CEE_AND, anded, shifted, diff);
-       MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, anded);
-}
-
 %%
 
 #ifdef MONO_ARCH_NEED_GOT_VAR
index aab2c9648d5e67da1c1e36d499c7abee08c93d22..dc220964f2be64d1b03489399a2e6fb86dee893d 100644 (file)
@@ -3554,22 +3554,6 @@ mono_find_jit_opcode_emulation (int opcode)
                return NULL;
 }
 
-static int
-is_unsigned_regsize_type (MonoType *type)
-{
-       switch (type->type) {
-       case MONO_TYPE_U1:
-       case MONO_TYPE_U2:
-       case MONO_TYPE_U4:
-#if SIZEOF_VOID_P == 8
-       /*case MONO_TYPE_U8: this requires different opcodes in inssel.brg */
-#endif
-               return TRUE;
-       default:
-               return FALSE;
-       }
-}
-
 static MonoInst*
 mini_get_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args)
 {
@@ -3666,21 +3650,11 @@ mini_get_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSigna
                store->inst_right = load;
                return store;
        } else if (cmethod->klass == mono_defaults.math_class) {
-               if (strcmp (cmethod->name, "Min") == 0) {
-                       if (is_unsigned_regsize_type (fsig->params [0])) {
-                               MONO_INST_NEW (cfg, ins, OP_MIN);
-                               ins->inst_i0 = args [0];
-                               ins->inst_i1 = args [1];
-                               return ins;
-                       }
-               } else if (strcmp (cmethod->name, "Max") == 0) {
-                       if (is_unsigned_regsize_type (fsig->params [0])) {
-                               MONO_INST_NEW (cfg, ins, OP_MAX);
-                               ins->inst_i0 = args [0];
-                               ins->inst_i1 = args [1];
-                               return ins;
-                       }
-               }
+               /* 
+                * There is general branches code for Min/Max, but it does not work for 
+                * all inputs:
+                * http://everything2.com/?node_id=1051618
+                */
        } else if (cmethod->klass->image == mono_defaults.corlib &&
                           (strcmp (cmethod->klass->name_space, "System.Threading") == 0) &&
                           (strcmp (cmethod->klass->name, "Interlocked") == 0)) {