This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix PR target/20446


The compiler produces broken assembly code at -O0 -fPIC -gstabs+ on a big C++ 
testcase involving virtual inheritance, a regression from 3.4 branch:

as: "sugarconverter.s", line 873: error: can't compute difference between
symbols in different segments

The problem comes from the mix of thunks and -fPIC in the SPARC back-end: both 
generate assembly directly and don't play nice with each other at -O0 because 
thunks go through the GOT instead of using a sibcall (-fdelayed-branch is 
disabled at -O0).

Fixed by deferring the special PIC helper when a thunk is the first function 
that goes through the GOT.  Bootstrapped/regtested on SPARC/Solaris 2.5, 2.6, 
7, 8 and 9 and tested with crosses to sparc-linux and sparc64-linux.

Applied to mainline and 4.0 branch.


2005-04-04  Eric Botcazou  <ebotcazou@libertysurf.fr>

	PR target/20446
	* config/sparc/sparc.h (NEED_INDICATE_EXEC_STACK): Define to 0.
	* config/sparc/linux.h (TARGET_ASM_FILE_END): Delete.
	(NEED_INDICATE_EXEC_STACK): Define to 1.
	* config/sparc/linux64.h (TARGET_ASM_FILE_END): Delete.
	(NEED_INDICATE_EXEC_STACK): Define to 1.
	* config/sparc/sparc.c (TARGET_ASM_FILE_END): Set to sparc_file_end.
	(add_pc_to_pic_symbol): Rename into pic_helper_symbol.
	(add_pc_to_pic_symbol_name): Rename into pic_helper_symbol_name.
	(pic_helper_emitted_p): New global.
	(emit_pic_helper): New function extracted from...
	(load_pic_register): ...here.  Add 'delay_pic_helper' parameter.
	Do not call emit_pic_helper if delay_pic_helper is true.
	(sparc_expand_prologue): Pass 'false' to load_pic_register.
	(sparc_output_mi_thunk): Pass 'true' to load_pic_register.
	(sparc_file_end): New function.


-- 
Eric Botcazou
Index: config/sparc/linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/linux.h,v
retrieving revision 1.68
diff -u -p -r1.68 linux.h
--- config/sparc/linux.h	20 Jan 2005 20:39:42 -0000	1.68
+++ config/sparc/linux.h	29 Mar 2005 16:24:28 -0000
@@ -209,8 +209,6 @@ do {									\
 #undef CTORS_SECTION_ASM_OP
 #undef DTORS_SECTION_ASM_OP
 
-#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
-
 /* Determine whether the the entire c99 runtime is present in the
    runtime library.  */
 #define TARGET_C99_FUNCTIONS 1
@@ -233,3 +231,6 @@ do {									\
    change their minds.  */
 #undef SPARC_RELAXED_ORDERING
 #define SPARC_RELAXED_ORDERING true
+
+#undef NEED_INDICATE_EXEC_STACK
+#define NEED_INDICATE_EXEC_STACK 1
Index: config/sparc/linux64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/linux64.h,v
retrieving revision 1.91
diff -u -p -r1.91 linux64.h
--- config/sparc/linux64.h	21 Jan 2005 10:15:56 -0000	1.91
+++ config/sparc/linux64.h	29 Mar 2005 16:24:29 -0000
@@ -343,8 +343,6 @@ do {									\
 #undef CTORS_SECTION_ASM_OP
 #undef DTORS_SECTION_ASM_OP
 
-#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
-
 /* Determine whether the the entire c99 runtime is present in the
    runtime library.  */
 #define TARGET_C99_FUNCTIONS 1
@@ -367,3 +365,6 @@ do {									\
    change their minds.  */
 #undef SPARC_RELAXED_ORDERING
 #define SPARC_RELAXED_ORDERING true
+
+#undef NEED_INDICATE_EXEC_STACK
+#define NEED_INDICATE_EXEC_STACK 1
Index: config/sparc/sparc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.c,v
retrieving revision 1.355
diff -u -p -r1.355 sparc.c
--- config/sparc/sparc.c	13 Mar 2005 22:11:46 -0000	1.355
+++ config/sparc/sparc.c	29 Mar 2005 16:24:49 -0000
@@ -314,7 +314,8 @@ static rtx sparc_builtin_saveregs (void)
 static int epilogue_renumber (rtx *, int);
 static bool sparc_assemble_integer (rtx, unsigned int, int);
 static int set_extends (rtx);
-static void load_pic_register (void);
+static void emit_pic_helper (void);
+static void load_pic_register (bool);
 static int save_or_restore_regs (int, int, rtx, int, int);
 static void emit_save_regs (void);
 static void emit_restore_regs (void);
@@ -362,6 +363,7 @@ static bool sparc_pass_by_reference (CUM
 static int sparc_arg_partial_bytes (CUMULATIVE_ARGS *,
 				    enum machine_mode, tree, bool);
 static void sparc_dwarf_handle_frame_unspec (const char *, rtx, int);
+static void sparc_file_end (void);
 #ifdef SUBTARGET_ATTRIBUTE_TABLE
 const struct attribute_spec sparc_attribute_table[];
 #endif
@@ -504,6 +506,8 @@ enum processor_type sparc_cpu;
 #undef TARGET_RELAXED_ORDERING
 #define TARGET_RELAXED_ORDERING SPARC_RELAXED_ORDERING
 
+#define TARGET_ASM_FILE_END sparc_file_end
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Validate and override various options, and do some machine dependent
@@ -3355,13 +3359,12 @@ sparc_cannot_force_const_mem (rtx x)
     }
 }
 
-/* The table we use to reference PIC data.  */
+/* PIC support.  */
+static GTY(()) char pic_helper_symbol_name[256];
+static GTY(()) rtx pic_helper_symbol;
+static GTY(()) bool pic_helper_emitted_p = false;
 static GTY(()) rtx global_offset_table;
 
-/* The function we use to get at it.  */
-static GTY(()) rtx add_pc_to_pic_symbol;
-static GTY(()) char add_pc_to_pic_symbol_name[256];
-
 /* Ensure that we are not using patterns that are not OK with PIC.  */
 
 int
@@ -3951,46 +3954,57 @@ legitimize_address (rtx x, rtx oldx ATTR
   return x;
 }
 
-/* Emit the special PIC prologue.  */
+/* Emit the special PIC helper function.  */
+
+static void
+emit_pic_helper (void)
+{
+  const char *pic_name = reg_names[REGNO (pic_offset_table_rtx)];
+  int align;
+
+  text_section ();
+
+  align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
+  if (align > 0)
+    ASM_OUTPUT_ALIGN (asm_out_file, align);
+  ASM_OUTPUT_LABEL (asm_out_file, pic_helper_symbol_name);
+  if (flag_delayed_branch)
+    fprintf (asm_out_file, "\tjmp\t%%o7+8\n\t add\t%%o7, %s, %s\n",
+	    pic_name, pic_name);
+  else
+    fprintf (asm_out_file, "\tadd\t%%o7, %s, %s\n\tjmp\t%%o7+8\n\t nop\n",
+	    pic_name, pic_name);
+
+  pic_helper_emitted_p = true;
+}
+
+/* Emit code to load the PIC register.  */
 
 static void
-load_pic_register (void)
+load_pic_register (bool delay_pic_helper)
 {
   int orig_flag_pic = flag_pic;
 
-  /* If we haven't emitted the special helper function, do so now.  */
-  if (add_pc_to_pic_symbol_name[0] == 0)
+  /* If we haven't initialized the special PIC symbols, do so now.  */
+  if (!pic_helper_symbol_name[0])
     {
-      const char *pic_name = reg_names[REGNO (pic_offset_table_rtx)];
-      int align;
-
-      ASM_GENERATE_INTERNAL_LABEL (add_pc_to_pic_symbol_name, "LADDPC", 0);
-      text_section ();
+      ASM_GENERATE_INTERNAL_LABEL (pic_helper_symbol_name, "LADDPC", 0);
+      pic_helper_symbol = gen_rtx_SYMBOL_REF (Pmode, pic_helper_symbol_name);
+      global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+    }
 
-      align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
-      if (align > 0)
-	ASM_OUTPUT_ALIGN (asm_out_file, align);
-      ASM_OUTPUT_LABEL (asm_out_file, add_pc_to_pic_symbol_name);
-      if (flag_delayed_branch)
-	fprintf (asm_out_file, "\tjmp %%o7+8\n\t add\t%%o7, %s, %s\n",
-		 pic_name, pic_name);
-      else
-	fprintf (asm_out_file, "\tadd\t%%o7, %s, %s\n\tjmp %%o7+8\n\t nop\n",
-		 pic_name, pic_name);
-    }
-
-  /* Initialize every time through, since we can't easily
-     know this to be permanent.  */
-  global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
-  add_pc_to_pic_symbol = gen_rtx_SYMBOL_REF (Pmode, add_pc_to_pic_symbol_name);
+  /* If we haven't emitted the special PIC helper function, do so now unless
+     we are requested to delay it.  */
+  if (!delay_pic_helper && !pic_helper_emitted_p)
+    emit_pic_helper ();
 
   flag_pic = 0;
   if (TARGET_ARCH64)
     emit_insn (gen_load_pcrel_symdi (pic_offset_table_rtx, global_offset_table,
-				     add_pc_to_pic_symbol));
+				     pic_helper_symbol));
   else
     emit_insn (gen_load_pcrel_symsi (pic_offset_table_rtx, global_offset_table,
-				     add_pc_to_pic_symbol));
+				     pic_helper_symbol));
   flag_pic = orig_flag_pic;
 
   /* Need to emit this whether or not we obey regdecls,
@@ -4639,7 +4653,7 @@ sparc_expand_prologue (void)
 
   /* Load the PIC register if needed.  */
   if (flag_pic && current_function_uses_pic_offset_table)
-    load_pic_register ();
+    load_pic_register (false);
 }
  
 /* This function generates the assembly code for function entry, which boils
@@ -9061,7 +9075,9 @@ sparc_output_mi_thunk (FILE *file, tree 
         {
 	  spill_reg = gen_rtx_REG (word_mode, 15);  /* %o7 */
 	  start_sequence ();
-	  load_pic_register ();  /* clobbers %o7 */
+	  /* Delay emitting the PIC helper function because it needs to
+	     change the section and we are emitting assembly code.  */
+	  load_pic_register (true);  /* clobbers %o7 */
 	  scratch = legitimize_pic_address (funexp, Pmode, scratch);
 	  seq = get_insns ();
 	  end_sequence ();
@@ -9212,4 +9228,15 @@ sparc_output_dwarf_dtprel (FILE *file, i
   fputs (")", file);
 }
 
+static
+void sparc_file_end (void)
+{
+  /* If we haven't emitted the special PIC helper function, do so now.  */
+  if (pic_helper_symbol_name[0] && !pic_helper_emitted_p)
+    emit_pic_helper ();
+
+  if (NEED_INDICATE_EXEC_STACK)
+    file_end_indicate_exec_stack ();
+}
+
 #include "gt-sparc.h"
Index: config/sparc/sparc.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.h,v
retrieving revision 1.273
diff -u -p -r1.273 sparc.h
--- config/sparc/sparc.h	21 Jan 2005 10:15:56 -0000	1.273
+++ config/sparc/sparc.h	29 Mar 2005 16:24:58 -0000
@@ -214,6 +214,9 @@ extern enum cmodel sparc_cmodel;
    total memory ordering (TMO).  */
 #define SPARC_RELAXED_ORDERING false
 
+/* Do not use the .note.GNU-stack convention by default.  */
+#define NEED_INDICATE_EXEC_STACK 0
+
 /* This is call-clobbered in the normal ABI, but is reserved in the
    home grown (aka upward compatible) embedded ABI.  */
 #define EMBMEDANY_BASE_REG "%g4"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]