The following patch fixes

          http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56847

Reload pass is lucky choosing alternative without offsettable memory in movti_internal pattern as this alternative for some reason has reject value less by one than alternative with offsettable memory. LRA chooses offsettable memory alternative as it looks cheaper and don't need secondary reload in alternative chosen by reload pass (and reload pass completely ignores this fact). LRA choice results in failure to generate insns for reloading address to make it offsettable.

  After several tries, I think I found a good solution for the problem.

The patch was successfully bootstrapped on x86 and x86-64 (with and without -fpie). I tried 500K lines of test code and did not find any difference in generated code using different options including -fpie. So the patch will not affect huge majority of the code.

  Committed as rev. 198101.

2013-04-19  Vladimir Makarov  <vmaka...@redhat.com>

        PR rtl-optimization/56847
        * lra-constraints.c (process_alt_operands): Discourage alternative
        with non-matche doffsettable memory constraint fro memory with
        known offset.

2013-04-19  Vladimir Makarov  <vmaka...@redhat.com>

        PR rtl-optimization/56847
        * gcc.dg/pr56847.c: New test.

Index: lra-constraints.c
===================================================================
--- lra-constraints.c   (revision 198092)
+++ lra-constraints.c   (working copy)
@@ -1978,8 +1978,15 @@ process_alt_operands (int only_alternati
                              (op, this_alternative) == NO_REGS))))
                reject += LRA_MAX_REJECT;
 
-             if (! ((const_to_mem && constmemok)
-                    || (MEM_P (op) && offmemok)))
+             if (MEM_P (op) && offmemok)
+               {
+                 /* If we know offset and this non-offsetable memory,
+                    something wrong with this memory and it is better
+                    to try other memory possibilities.  */
+                 if (MEM_OFFSET_KNOWN_P (op))
+                   reject += LRA_MAX_REJECT;
+               }
+             else if (! (const_to_mem && constmemok))
                {
                  /* We prefer to reload pseudos over reloading other
                     things, since such reloads may be able to be
Index: testsuite/gcc.dg/pr56847.c
===================================================================
--- testsuite/gcc.dg/pr56847.c  (revision 0)
+++ testsuite/gcc.dg/pr56847.c  (working copy)
@@ -0,0 +1,12 @@
+/* PR rtl-optimization/56847 */
+/* { dg-do compile { target pie } } */
+/* { dg-options "-O2 -fpie" } */
+
+struct S { long int a, b; } e;
+__thread struct S s;
+
+void
+foo (void)
+{
+  s = e;
+}

Reply via email to