On 2014-08-29 2:47 AM, Ilya Enkovich wrote:
Seems your patch doesn't cover all cases.  Attached is a modified
patch (with your changes included) and a test where double constant is
wrongly rematerialized.  I also see in ira dump that there is still a
copy of PIC reg created:

Initialization of original PIC reg:
(insn 23 22 24 2 (set (reg:SI 127)
         (reg:SI 3 bx)) test.cc:42 90 {*movsi_internal}
      (expr_list:REG_DEAD (reg:SI 3 bx)
         (nil)))
...
Copy is created:
(insn 135 37 25 3 (set (reg:SI 138 [127])
         (reg:SI 127)) 90 {*movsi_internal}
      (expr_list:REG_DEAD (reg:SI 127)
         (nil)))
...
Copy is used:
(insn 119 25 122 3 (set (reg:DF 134)
         (mem/u/c:DF (plus:SI (reg:SI 138 [127])
                 (const:SI (unspec:SI [
                             (symbol_ref/u:SI ("*.LC0") [flags 0x2])
                         ] UNSPEC_GOTOFF))) [5  S8 A64])) 128 {*movdf_internal}
      (expr_list:REG_EQUIV (const_double:DF
2.9999999999999997371893933895137251965934410691261292e-4
[0x0.9d495182a99308p-11])
         (nil)))


The copy is created by a newer IRA optimization for function prologues.

The patch in the attachment should solve the problem. I also added the code to prevent spilling the pic pseudo in LRA which could happen before theoretically.


After reload we have new usage of r127 which is allocated to ecx which
actually does not have any definition in this function at all.

(insn 151 42 44 4 (set (reg:SI 0 ax [147])
         (plus:SI (reg:SI 2 cx [127])
             (const:SI (unspec:SI [
                         (symbol_ref/u:SI ("*.LC0") [flags 0x2])
                     ] UNSPEC_GOTOFF)))) test.cc:44 213 {*leasi}
      (expr_list:REG_EQUAL (symbol_ref/u:SI ("*.LC0") [flags 0x2])
         (nil)))
(insn 44 151 45 4 (set (reg:DF 21 xmm0 [orig:129 D.2450 ] [129])
         (mult:DF (reg:DF 21 xmm0 [orig:128 D.2450 ] [128])
             (mem/u/c:DF (reg:SI 0 ax [147]) [5  S8 A64]))) test.cc:44
790 {*fop_df_comm_sse}
      (expr_list:REG_EQUAL (mult:DF (reg:DF 21 xmm0 [orig:128 D.2450 ] [128])
             (const_double:DF
2.9999999999999997371893933895137251965934410691261292e-4
[0x0.9d495182a99308p-11]))
         (nil)))

Compilation string: g++ -m32 -O2 -mfpmath=sse -fPIE -S test.cc

Index: ira.c
===================================================================
--- ira.c       (revision 214576)
+++ ira.c       (working copy)
@@ -4887,7 +4887,7 @@ split_live_ranges_for_shrink_wrap (void)
   FOR_BB_INSNS (first, insn)
     {
       rtx dest = interesting_dest_for_shprep (insn, call_dom);
-      if (!dest)
+      if (!dest || dest == pic_offset_table_rtx)
        continue;
 
       rtx newreg = NULL_RTX;
Index: lra-assigns.c
===================================================================
--- lra-assigns.c       (revision 214576)
+++ lra-assigns.c       (working copy)
@@ -879,11 +879,13 @@ spill_for (int regno, bitmap spilled_pse
        }
       /* Spill pseudos.         */
       EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
-       if ((int) spill_regno >= lra_constraint_new_regno_start
-           && ! bitmap_bit_p (&lra_inheritance_pseudos, spill_regno)
-           && ! bitmap_bit_p (&lra_split_regs, spill_regno)
-           && ! bitmap_bit_p (&lra_subreg_reload_pseudos, spill_regno)
-           && ! bitmap_bit_p (&lra_optional_reload_pseudos, spill_regno))
+       if ((pic_offset_table_rtx != NULL
+            && spill_regno == REGNO (pic_offset_table_rtx))
+           || ((int) spill_regno >= lra_constraint_new_regno_start
+               && ! bitmap_bit_p (&lra_inheritance_pseudos, spill_regno)
+               && ! bitmap_bit_p (&lra_split_regs, spill_regno)
+               && ! bitmap_bit_p (&lra_subreg_reload_pseudos, spill_regno)
+               && ! bitmap_bit_p (&lra_optional_reload_pseudos, spill_regno)))
          goto fail;
       insn_pseudos_num = 0;
       if (lra_dump_file != NULL)
@@ -1053,7 +1055,9 @@ setup_live_pseudos_and_spill_after_risky
       return;
     }
   for (n = 0, i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
-    if (reg_renumber[i] >= 0 && lra_reg_info[i].nrefs > 0)
+    if ((pic_offset_table_rtx == NULL_RTX
+        || i != (int) REGNO (pic_offset_table_rtx))
+       && reg_renumber[i] >= 0 && lra_reg_info[i].nrefs > 0)
       sorted_pseudos[n++] = i;
   qsort (sorted_pseudos, n, sizeof (int), pseudo_compare_func);
   for (i = n - 1; i >= 0; i--)
@@ -1360,6 +1364,8 @@ assign_by_spills (void)
        }
       EXECUTE_IF_SET_IN_SPARSESET (live_range_hard_reg_pseudos, conflict_regno)
        {
+         gcc_assert (pic_offset_table_rtx == NULL
+                     || conflict_regno != REGNO (pic_offset_table_rtx));
          if ((int) conflict_regno >= lra_constraint_new_regno_start)
            sorted_pseudos[nfails++] = conflict_regno;
          if (lra_dump_file != NULL)

Reply via email to