2009-05-20 Rodrigo Kumpera <rkumpera@novell.com>
authorRodrigo Kumpera <kumpera@gmail.com>
Wed, 20 May 2009 19:27:13 +0000 (19:27 -0000)
committerRodrigo Kumpera <kumpera@gmail.com>
Wed, 20 May 2009 19:27:13 +0000 (19:27 -0000)
* local-propagation.c (mono_local_cprop): Avoid local propagation
across paired add/sub if the first instruction dest reg is it's
source reg. For example:

int_add_imm R12 <- R12 [1] clobbers: 1
int_sub_imm R42 <- R12 [1] clobbers: 1

The cprop pass would wrongly const prop + 1 to int_sub_imm which doesn't
maintain the math identify.

Fixes #505375.

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

mono/mini/ChangeLog
mono/mini/basic.cs
mono/mini/local-propagation.c

index cd8d9a8bd5ef8600eb0ff228338c157ec9d3af94..fa420726773e4444df5464881b53272e120e93a5 100644 (file)
@@ -1,3 +1,17 @@
+2009-05-20 Rodrigo Kumpera  <rkumpera@novell.com>
+
+       * local-propagation.c (mono_local_cprop): Avoid local propagation
+       across paired add/sub if the first instruction dest reg is it's
+       source reg. For example:
+
+       int_add_imm R12 <- R12 [1] clobbers: 1
+       int_sub_imm R42 <- R12 [1] clobbers: 1
+
+       The cprop pass would wrongly const prop + 1 to int_sub_imm which doesn't
+       maintain the math identify.
+
+       Fixes #505375.
+
 2009-05-20  Andreia Gaita  <avidigal@novell.com>
 
        * Makefile.am: avoid going on the network just to get the revision,
index 74d1ede1fad72f11ac21e1b961f698dae738bf77..3f736d506932733084a923eb9f1bbc5907a91fd9 100644 (file)
@@ -1325,4 +1325,17 @@ class Tests {
                        return 2;
                return 0;
        }
+
+       //repro for #505375
+       public static int test_2_cprop_bug () {
+               int idx = 0;
+               int a = 1;
+               var cmp = System.Collections.Generic.Comparer<int>.Default ;
+               if (cmp.Compare (a, 0) > 0)
+                       a = 0;
+               do { idx++; } while (cmp.Compare (idx - 1, a) == 0);
+               return idx;
+       }
+
+
 }
index 51bc65a0c15ca261976ac265fbb801f5cd33192e..3c76408f3e44ce31d0e4869c3e51aec8ba7549be 100644 (file)
@@ -121,7 +121,7 @@ restart:
 
                                        if ((def->opcode == OP_MOVE) && (!defs [def->sreg1] || (def_index [def->sreg1] < def_index [sreg])) && !vreg_is_volatile (cfg, def->sreg1)) {
                                                int vreg = def->sreg1;
-                                               //printf ("CCOPY: R%d -> R%d\n", sreg, vreg);
+                                               if (cfg->verbose_level > 2) printf ("CCOPY: R%d -> R%d\n", sreg, vreg);
                                                ins->dreg = vreg;
                                        }
                                }
@@ -170,7 +170,7 @@ restart:
                                        (def->opcode != OP_FMOVE)) {
                                        int vreg = def->sreg1;
 
-                                       //printf ("CCOPY: R%d -> R%d\n", sreg, vreg);
+                                       if (cfg->verbose_level > 2) printf ("CCOPY/2: R%d -> R%d\n", sreg, vreg);
                                        sregs [srcindex] = vreg;
                                        mono_inst_set_src_registers (ins, sregs);
 
@@ -257,10 +257,10 @@ restart:
                                                ins->inst_basereg = def->sreg1;
                                                ins->inst_offset += def->inst_imm;
                                        }
-                               } else if ((ins->opcode == OP_ISUB_IMM) && (def->opcode == OP_IADD_IMM) && (def->next == ins)) {
+                               } else if ((ins->opcode == OP_ISUB_IMM) && (def->opcode == OP_IADD_IMM) && (def->next == ins) && (def->dreg != def->sreg1)) {
                                        ins->sreg1 = def->sreg1;
                                        ins->inst_imm -= def->inst_imm;
-                               } else if ((ins->opcode == OP_IADD_IMM) && (def->opcode == OP_ISUB_IMM) && (def->next == ins)) {
+                               } else if ((ins->opcode == OP_IADD_IMM) && (def->opcode == OP_ISUB_IMM) && (def->next == ins) && (def->dreg != def->sreg1)) {
                                        ins->sreg1 = def->sreg1;
                                        ins->inst_imm -= def->inst_imm;
                                } else if (ins->opcode == OP_STOREI1_MEMBASE_REG &&