[SPARC] Fix PR target/92095
diff mbox series

Message ID 4290067.bLcTDpm7Ge@polaris
State New
Headers show
Series
  • [SPARC] Fix PR target/92095
Related show

Commit Message

Eric Botcazou Nov. 8, 2019, 12:31 p.m. UTC
This is a regression present on mainline and 9/8 branches which was introduced 
by my fix for PR target/91472, another regression present on the branches:
  https://gcc.gnu.org/ml/gcc-patches/2019-09/msg00012.html
They are ultimately all fallout of the transition to a pseudo PIC register for 
the SPARC port, which turns out to be more disruptive than initially thought.

Bootstrapped/regtested on SPARC64/Linux and SPARC/Solaris, applied on mainline 
and 9/8 branches.


2019-11-08  Eric Botcazou  <ebotcazou@adacore.com>

	PR target/92095
	* config/sparc/sparc-protos.h (output_load_pcrel_sym): Declare.
	* config/sparc/sparc.c (sparc_cannot_force_const_mem): Revert latest
 	change.
	(got_helper_needed): New static variable.
	(output_load_pcrel_sym): New function.
	(get_pc_thunk_name): Remove after inlining...
	(load_got_register): ...here.  Rework the initialization of the GOT
	register and of the GOT helper.
	(save_local_or_in_reg_p): Test the REGNO of the GOT register.
	(sparc_file_end): Test got_helper_needed to decide whether the GOT
	helper must be emitted.  Use output_asm_insn instead of fprintf.
	(sparc_init_pic_reg): In PIC mode, always initialize the PIC register
	if optimization is enabled.
	* config/sparc/sparc.md (load_pcrel_sym<P:mode>): Emit the assembly
	by calling output_load_pcrel_sym.


2019-11-08  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.c-torture/compile/20191108-1.c: New test.
	* gcc.target/sparc/overflow-3.c: Add -fno-pie to the options.
	* gcc.target/sparc/overflow-4.c: Likewise.
	* gcc.target/sparc/overflow-5.c: Likewise.

Patch
diff mbox series

Index: config/sparc/sparc-protos.h
===================================================================
--- config/sparc/sparc-protos.h	(revision 277906)
+++ config/sparc/sparc-protos.h	(working copy)
@@ -69,6 +69,7 @@  extern void sparc_split_reg_mem (rtx, rt
 extern void sparc_split_mem_reg (rtx, rtx, machine_mode);
 extern int sparc_split_reg_reg_legitimate (rtx, rtx);
 extern void sparc_split_reg_reg (rtx, rtx, machine_mode);
+extern const char *output_load_pcrel_sym (rtx *);
 extern const char *output_ubranch (rtx, rtx_insn *);
 extern const char *output_cbranch (rtx, rtx, int, int, int, rtx_insn *);
 extern const char *output_return (rtx_insn *);
Index: config/sparc/sparc.c
===================================================================
--- config/sparc/sparc.c	(revision 277906)
+++ config/sparc/sparc.c	(working copy)
@@ -4201,13 +4201,6 @@  eligible_for_sibcall_delay (rtx_insn *tr
 static bool
 sparc_cannot_force_const_mem (machine_mode mode, rtx x)
 {
-  /* After IRA has run in PIC mode, it is too late to put anything into the
-     constant pool if the PIC register hasn't already been initialized.  */
-  if ((lra_in_progress || reload_in_progress)
-      && flag_pic
-      && !crtl->uses_pic_offset_table)
-    return true;
-
   switch (GET_CODE (x))
     {
     case CONST_INT:
@@ -4243,9 +4236,11 @@  sparc_cannot_force_const_mem (machine_mo
 }
 
 /* Global Offset Table support.  */
-static GTY(()) rtx got_helper_rtx = NULL_RTX;
-static GTY(()) rtx got_register_rtx = NULL_RTX;
 static GTY(()) rtx got_symbol_rtx = NULL_RTX;
+static GTY(()) rtx got_register_rtx = NULL_RTX;
+static GTY(()) rtx got_helper_rtx = NULL_RTX;
+
+static GTY(()) bool got_helper_needed = false;
 
 /* Return the SYMBOL_REF for the Global Offset Table.  */
 
@@ -4258,27 +4253,6 @@  sparc_got (void)
   return got_symbol_rtx;
 }
 
-#ifdef HAVE_GAS_HIDDEN
-# define USE_HIDDEN_LINKONCE 1
-#else
-# define USE_HIDDEN_LINKONCE 0
-#endif
-
-static void
-get_pc_thunk_name (char name[32], unsigned int regno)
-{
-  const char *reg_name = reg_names[regno];
-
-  /* Skip the leading '%' as that cannot be used in a
-     symbol name.  */
-  reg_name += 1;
-
-  if (USE_HIDDEN_LINKONCE)
-    sprintf (name, "__sparc_get_pc_thunk.%s", reg_name);
-  else
-    ASM_GENERATE_INTERNAL_LABEL (name, "LADDPC", regno);
-}
-
 /* Wrapper around the load_pcrel_sym{si,di} patterns.  */
 
 static rtx
@@ -4298,30 +4272,78 @@  gen_load_pcrel_sym (rtx op0, rtx op1, rt
   return insn;
 }
 
+/* Output the load_pcrel_sym{si,di} patterns.  */
+
+const char *
+output_load_pcrel_sym (rtx *operands)
+{
+  if (flag_delayed_branch)
+    {
+      output_asm_insn ("sethi\t%%hi(%a1-4), %0", operands);
+      output_asm_insn ("call\t%a2", operands);
+      output_asm_insn (" add\t%0, %%lo(%a1+4), %0", operands);
+    }
+  else
+    {
+      output_asm_insn ("sethi\t%%hi(%a1-8), %0", operands);
+      output_asm_insn ("add\t%0, %%lo(%a1-4), %0", operands);
+      output_asm_insn ("call\t%a2", operands);
+      output_asm_insn (" nop", NULL);
+    }
+
+  if (operands[2] == got_helper_rtx)
+    got_helper_needed = true;
+
+  return "";
+}
+
+#ifdef HAVE_GAS_HIDDEN
+# define USE_HIDDEN_LINKONCE 1
+#else
+# define USE_HIDDEN_LINKONCE 0
+#endif
+
 /* Emit code to load the GOT register.  */
 
 void
 load_got_register (void)
 {
-  if (!got_register_rtx)
-    got_register_rtx = gen_rtx_REG (Pmode, GLOBAL_OFFSET_TABLE_REGNUM);
+  rtx insn;
 
   if (TARGET_VXWORKS_RTP)
-    emit_insn (gen_vxworks_load_got ());
+    {
+      if (!got_register_rtx)
+	got_register_rtx = pic_offset_table_rtx;
+
+      insn = gen_vxworks_load_got ();
+    }
   else
     {
+      if (!got_register_rtx)
+	got_register_rtx = gen_rtx_REG (Pmode, GLOBAL_OFFSET_TABLE_REGNUM);
+
       /* The GOT symbol is subject to a PC-relative relocation so we need a
 	 helper function to add the PC value and thus get the final value.  */
       if (!got_helper_rtx)
 	{
 	  char name[32];
-	  get_pc_thunk_name (name, GLOBAL_OFFSET_TABLE_REGNUM);
+
+	  /* Skip the leading '%' as that cannot be used in a symbol name.  */
+	  if (USE_HIDDEN_LINKONCE)
+	    sprintf (name, "__sparc_get_pc_thunk.%s",
+		     reg_names[REGNO (got_register_rtx)] + 1);
+	  else
+	    ASM_GENERATE_INTERNAL_LABEL (name, "LADDPC",
+					 REGNO (got_register_rtx));
+
 	  got_helper_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
 	}
 
-      emit_insn (gen_load_pcrel_sym (got_register_rtx, sparc_got (),
-				     got_helper_rtx));
+      insn
+	= gen_load_pcrel_sym (got_register_rtx, sparc_got (), got_helper_rtx);
     }
+
+  emit_insn (insn);
 }
 
 /* Ensure that we are not using patterns that are not OK with PIC.  */
@@ -5486,7 +5508,7 @@  save_local_or_in_reg_p (unsigned int reg
     return true;
 
   /* GOT register (%l7) if needed.  */
-  if (regno == GLOBAL_OFFSET_TABLE_REGNUM && got_register_rtx)
+  if (got_register_rtx && regno == REGNO (got_register_rtx))
     return true;
 
   /* If the function accesses prior frames, the frame pointer and the return
@@ -12529,10 +12551,9 @@  static void
 sparc_file_end (void)
 {
   /* If we need to emit the special GOT helper function, do so now.  */
-  if (got_helper_rtx)
+  if (got_helper_needed)
     {
       const char *name = XSTR (got_helper_rtx, 0);
-      const char *reg_name = reg_names[GLOBAL_OFFSET_TABLE_REGNUM];
 #ifdef DWARF2_UNWIND_INFO
       bool do_cfi;
 #endif
@@ -12569,17 +12590,22 @@  sparc_file_end (void)
 #ifdef DWARF2_UNWIND_INFO
       do_cfi = dwarf2out_do_cfi_asm ();
       if (do_cfi)
-	fprintf (asm_out_file, "\t.cfi_startproc\n");
+	output_asm_insn (".cfi_startproc", NULL);
 #endif
       if (flag_delayed_branch)
-	fprintf (asm_out_file, "\tjmp\t%%o7+8\n\t add\t%%o7, %s, %s\n",
-		 reg_name, reg_name);
+	{
+	  output_asm_insn ("jmp\t%%o7+8", NULL);
+	  output_asm_insn (" add\t%%o7, %0, %0", &got_register_rtx);
+	}
       else
-	fprintf (asm_out_file, "\tadd\t%%o7, %s, %s\n\tjmp\t%%o7+8\n\t nop\n",
-		 reg_name, reg_name);
+	{
+	  output_asm_insn ("add\t%%o7, %0, %0", &got_register_rtx);
+	  output_asm_insn ("jmp\t%%o7+8", NULL);
+	  output_asm_insn (" nop", NULL);
+	}
 #ifdef DWARF2_UNWIND_INFO
       if (do_cfi)
-	fprintf (asm_out_file, "\t.cfi_endproc\n");
+	output_asm_insn (".cfi_endproc", NULL);
 #endif
     }
 
@@ -13074,7 +13100,10 @@  sparc_init_pic_reg (void)
   edge entry_edge;
   rtx_insn *seq;
 
-  if (!crtl->uses_pic_offset_table)
+  /* In PIC mode, we need to always initialize the PIC register if optimization
+     is enabled, because we are called from IRA and LRA may later force things
+     to the constant pool for optimization purposes.  */
+  if (!flag_pic || (!crtl->uses_pic_offset_table && !optimize))
     return;
 
   start_sequence ();
Index: config/sparc/sparc.md
===================================================================
--- config/sparc/sparc.md	(revision 277906)
+++ config/sparc/sparc.md	(working copy)
@@ -1604,10 +1604,7 @@  (define_insn "load_pcrel_sym<P:mode>"
    (clobber (reg:P O7_REG))]
   "REGNO (operands[0]) == INTVAL (operands[3])"
 {
-  if (flag_delayed_branch)
-    return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
-  else
-    return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
+  return output_load_pcrel_sym (operands);
 }
   [(set (attr "type") (const_string "multi"))
    (set (attr "length")
Index: testsuite/gcc.target/sparc/overflow-3.c
===================================================================
--- testsuite/gcc.target/sparc/overflow-3.c	(revision 277906)
+++ testsuite/gcc.target/sparc/overflow-3.c	(working copy)
@@ -1,6 +1,6 @@ 
 /* { dg-do compile } */
 /* { dg-require-effective-target lp64 } */
-/* { dg-options "-O" } */
+/* { dg-options "-O -fno-pie" } */
 
 #include <stdbool.h>
 #include <stdint.h>
Index: testsuite/gcc.target/sparc/overflow-4.c
===================================================================
--- testsuite/gcc.target/sparc/overflow-4.c	(revision 277906)
+++ testsuite/gcc.target/sparc/overflow-4.c	(working copy)
@@ -1,6 +1,6 @@ 
 /* { dg-do compile } */
 /* { dg-require-effective-target lp64 } */
-/* { dg-options "-O -mno-vis3 -mno-vis4" } */
+/* { dg-options "-O -fno-pie -mno-vis3 -mno-vis4" } */
 
 #include <stdbool.h>
 #include <stdint.h>
Index: testsuite/gcc.target/sparc/overflow-5.c
===================================================================
--- testsuite/gcc.target/sparc/overflow-5.c	(revision 277906)
+++ testsuite/gcc.target/sparc/overflow-5.c	(working copy)
@@ -1,6 +1,6 @@ 
 /* { dg-do compile } */
 /* { dg-require-effective-target lp64 } */
-/* { dg-options "-O -mvis3" } */
+/* { dg-options "-O -fno-pie -mvis3" } */
 
 #include <stdbool.h>
 #include <stdint.h>