diff mbox

Enable EBX for x86 in 32bits PIC code

Message ID 540777C0.9050106@redhat.com
State New
Headers show

Commit Message

Vladimir Makarov Sept. 3, 2014, 8:19 p.m. UTC
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
diff mbox

Patch

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)