re PR target/92095 (internal error with -O1 -mcpu=niagara2 -fPIE)
authorEric Botcazou <ebotcazou@adacore.com>
Fri, 8 Nov 2019 12:30:47 +0000 (12:30 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Fri, 8 Nov 2019 12:30:47 +0000 (12:30 +0000)
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.

From-SVN: r277966

gcc/ChangeLog
gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/20191108-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/sparc/overflow-3.c
gcc/testsuite/gcc.target/sparc/overflow-4.c
gcc/testsuite/gcc.target/sparc/overflow-5.c

index 519896d..a2f30cf 100644 (file)
@@ -1,3 +1,22 @@
+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  Richard Sandiford  <richard.sandiford@arm.com>
 
        * tree-sra.c (create_access): Delay disqualifying the base
index 9bdae7b..ef1adb6 100644 (file)
@@ -69,6 +69,7 @@ extern void sparc_split_reg_mem (rtx, rtx, machine_mode);
 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 fe5e941..75b3d4e 100644 (file)
@@ -4201,13 +4201,6 @@ eligible_for_sibcall_delay (rtx_insn *trial)
 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_mode mode, rtx x)
 }
 \f
 /* 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, rtx op2)
   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 regno, int leaf_function)
     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 7af62d5..0a6e27f 100644 (file)
    (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 06ec402..286e6e1 100644 (file)
@@ -1,3 +1,10 @@
+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.
+
 2019-11-08  Richard Sandiford  <richard.sandiford@arm.com>
 
        * gcc.target/aarch64/sve/acle/general/inline_2.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/compile/20191108-1.c b/gcc/testsuite/gcc.c-torture/compile/20191108-1.c
new file mode 100644 (file)
index 0000000..7929751
--- /dev/null
@@ -0,0 +1,14 @@
+/* PR target/92095 */
+/* Testcase by Sergei Trofimovich <slyfox@inbox.ru> */
+
+typedef union {
+  double a;
+  int b[2];
+} c;
+
+double d(int e)
+{
+  c f;
+  (&f)->b[0] = 15728640;
+  return e ? -(&f)->a : (&f)->a;
+}
index 86dddfb..52d6ab2 100644 (file)
@@ -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 019feee..c6121b9 100644 (file)
@@ -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 67d4ac3..f00283f 100644 (file)
@@ -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>