Patchwork Fix twolf -funroll-loops -O3 miscompilation (a semi-latent web.c bug)

login
register
mail settings
Submitter Steven Bosscher
Date Nov. 27, 2012, 12:28 p.m.
Message ID <CABu31nN_E7dFWE8eUH+wnencZSEHR+Mcyuhtv2f1PkrdSmS3Yg@mail.gmail.com>
Download mbox | patch
Permalink /patch/202201/
State New
Headers show

Comments

Steven Bosscher - Nov. 27, 2012, 12:28 p.m.
On Tue, Nov 27, 2012 at 1:00 PM, Steven Bosscher wrote:
> Now that USE of r719 is a use of a dead register, rendering the
> REG_EQUAL invalid. From there on the problem is the same as the ones I
> had to "fix" in loop-unroll.c. First the webizer puts the USE in a
> different web and renames the USE to r1591:
>
>  2889 r719:DI=r1562:DI
>       REG_EQUAL: r1591:DI+0x4

With this patch, the self-referencing EQ_USE is kept together with its DEF:

 2889 r719:DI=r1562:DI
      REG_EQUAL: r719:DI+0x4

Dominique, could you give this a try and see if it helps?
(But as I said up-thread: I'm not sure this is a proper fix, or just
another band-aid...)

Ciao!
Steven


        * web.c (union_eq_uses): New function to keep self-referencing
notes intact.
        (web_main): Call it.
Dominique Dhumieres - Nov. 27, 2012, 1:47 p.m.
> Dominique, could you give this a try and see if it helps?

With the patch, the miscompilation of aermod.f90 is gone.

Thanks,

Dominique

Patch

Index: web.c
===================================================================
--- web.c       (revision 193394)
+++ web.c       (working copy)
@@ -148,6 +148,35 @@  union_match_dups (rtx insn, struct web_e
     }
 }

+/* If INSN has a REG_EQUAL note that references a DEF of INSN, union
+   them.  FUN is the function that does the union.  */
+
+static void
+union_eq_uses (rtx insn, struct web_entry *def_entry,
+              struct web_entry *use_entry,
+              bool (*fun) (struct web_entry *, struct web_entry *))
+{
+  struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
+  df_ref *def_link = DF_INSN_INFO_DEFS (insn_info);
+  df_ref *eq_use_link = DF_INSN_INFO_EQ_USES (insn_info);
+
+  if (! (def_link && eq_use_link))
+    return;
+
+  while (*eq_use_link)
+    {
+      df_ref *def_rec = def_link;
+      while (*def_rec)
+       {
+         if (DF_REF_REAL_REG (*eq_use_link) == DF_REF_REAL_REG (*def_rec))
+           (*fun) (use_entry + DF_REF_ID (*eq_use_link),
+                   def_entry + DF_REF_ID (*def_rec));
+         def_rec++;
+       }
+      eq_use_link++;
+    }
+}
+
 /* For each use, all possible defs reaching it must come in the same
    register, union them.
    FUN is the function that does the union.
@@ -390,6 +419,7 @@  web_main (void)
              if (DF_REF_REGNO (use) >= FIRST_PSEUDO_REGISTER)
                union_defs (use, def_entry, used, use_entry, unionfind_union);
            }
+         union_eq_uses (insn, def_entry, use_entry, unionfind_union);
        }
     }