2021-04-11 11:47:36 +02:00
|
|
|
|
From 0824d6819857f306583592bce96315893f91bd84 Mon Sep 17 00:00:00 2001
|
2021-01-21 00:02:34 +01:00
|
|
|
|
From: Romain Naour <romain.naour@gmail.com>
|
|
|
|
|
Date: Wed, 20 Jan 2021 23:26:29 +0100
|
|
|
|
|
Subject: [PATCH] Revert "re PR target/92095 (internal error with -O1
|
|
|
|
|
-mcpu=niagara2 -fPIE)"
|
|
|
|
|
|
|
|
|
|
This reverts commit 0a83f1a441d7aaadecb368c237b6ee70bd7b91d6.
|
|
|
|
|
|
|
|
|
|
Building the Buildroot defconfig qemu_sparc_ss10_defconfig using
|
|
|
|
|
gcc 8.4, 9.3 and 10 produce a broken rootfs that trigger illegal
|
|
|
|
|
instruction messages.
|
|
|
|
|
|
|
|
|
|
gcc 8.3, 9.2 are the latest working gcc version.
|
|
|
|
|
git bisect between gcc 8.4 and 8.4 allowed to identify
|
|
|
|
|
the commit that introcuce the regression.
|
|
|
|
|
|
|
|
|
|
Reverting this patch allowed to produce a working rootfs.
|
|
|
|
|
|
2021-04-11 11:47:36 +02:00
|
|
|
|
Reported to gcc:
|
|
|
|
|
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98784
|
|
|
|
|
|
2021-01-21 00:02:34 +01:00
|
|
|
|
Signed-off-by: Romain Naour <romain.naour@gmail.com>
|
|
|
|
|
Cc: Eric Botcazou <ebotcazou@gcc.gnu.org>
|
|
|
|
|
---
|
|
|
|
|
gcc/config/sparc/sparc-protos.h | 1 -
|
|
|
|
|
gcc/config/sparc/sparc.c | 121 +++++++-----------
|
|
|
|
|
gcc/config/sparc/sparc.md | 5 +-
|
|
|
|
|
.../gcc.c-torture/compile/20191108-1.c | 14 --
|
|
|
|
|
gcc/testsuite/gcc.target/sparc/overflow-3.c | 2 +-
|
|
|
|
|
gcc/testsuite/gcc.target/sparc/overflow-4.c | 2 +-
|
|
|
|
|
gcc/testsuite/gcc.target/sparc/overflow-5.c | 2 +-
|
|
|
|
|
7 files changed, 53 insertions(+), 94 deletions(-)
|
|
|
|
|
delete mode 100644 gcc/testsuite/gcc.c-torture/compile/20191108-1.c
|
|
|
|
|
|
|
|
|
|
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
|
2021-04-11 11:47:36 +02:00
|
|
|
|
index 5f9999a669c..37452b06415 100644
|
2021-01-21 00:02:34 +01:00
|
|
|
|
--- a/gcc/config/sparc/sparc-protos.h
|
|
|
|
|
+++ b/gcc/config/sparc/sparc-protos.h
|
|
|
|
|
@@ -69,7 +69,6 @@ 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 *);
|
|
|
|
|
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
|
2021-04-11 11:47:36 +02:00
|
|
|
|
index d0843102148..14d112d8ca8 100644
|
2021-01-21 00:02:34 +01:00
|
|
|
|
--- a/gcc/config/sparc/sparc.c
|
|
|
|
|
+++ b/gcc/config/sparc/sparc.c
|
2021-04-11 11:47:36 +02:00
|
|
|
|
@@ -4157,6 +4157,13 @@ eligible_for_sibcall_delay (rtx_insn *trial)
|
2021-01-21 00:02:34 +01:00
|
|
|
|
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:
|
2021-04-11 11:47:36 +02:00
|
|
|
|
@@ -4192,11 +4199,9 @@ sparc_cannot_force_const_mem (machine_mode mode, rtx x)
|
2021-01-21 00:02:34 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Global Offset Table support. */
|
|
|
|
|
-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;
|
|
|
|
|
+static GTY(()) rtx got_register_rtx = NULL_RTX;
|
|
|
|
|
+static GTY(()) rtx got_symbol_rtx = NULL_RTX;
|
|
|
|
|
|
|
|
|
|
/* Return the SYMBOL_REF for the Global Offset Table. */
|
|
|
|
|
|
2021-04-11 11:47:36 +02:00
|
|
|
|
@@ -4209,6 +4214,27 @@ sparc_got (void)
|
2021-01-21 00:02:34 +01:00
|
|
|
|
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
|
2021-04-11 11:47:36 +02:00
|
|
|
|
@@ -4228,78 +4254,30 @@ gen_load_pcrel_sym (rtx op0, rtx op1, rtx op2)
|
2021-01-21 00:02:34 +01:00
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
- rtx insn;
|
|
|
|
|
+ if (!got_register_rtx)
|
|
|
|
|
+ got_register_rtx = gen_rtx_REG (Pmode, GLOBAL_OFFSET_TABLE_REGNUM);
|
|
|
|
|
|
|
|
|
|
if (TARGET_VXWORKS_RTP)
|
|
|
|
|
- {
|
|
|
|
|
- if (!got_register_rtx)
|
|
|
|
|
- got_register_rtx = pic_offset_table_rtx;
|
|
|
|
|
-
|
|
|
|
|
- insn = gen_vxworks_load_got ();
|
|
|
|
|
- }
|
|
|
|
|
+ emit_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];
|
|
|
|
|
-
|
|
|
|
|
- /* 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));
|
|
|
|
|
-
|
|
|
|
|
+ get_pc_thunk_name (name, GLOBAL_OFFSET_TABLE_REGNUM);
|
|
|
|
|
got_helper_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- insn
|
|
|
|
|
- = gen_load_pcrel_sym (got_register_rtx, sparc_got (), got_helper_rtx);
|
|
|
|
|
+ emit_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. */
|
2021-04-11 11:47:36 +02:00
|
|
|
|
@@ -5464,7 +5442,7 @@ save_local_or_in_reg_p (unsigned int regno, int leaf_function)
|
2021-01-21 00:02:34 +01:00
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
/* GOT register (%l7) if needed. */
|
|
|
|
|
- if (got_register_rtx && regno == REGNO (got_register_rtx))
|
|
|
|
|
+ if (regno == GLOBAL_OFFSET_TABLE_REGNUM && got_register_rtx)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
/* If the function accesses prior frames, the frame pointer and the return
|
2021-04-11 11:47:36 +02:00
|
|
|
|
@@ -12507,9 +12485,10 @@ static void
|
2021-01-21 00:02:34 +01:00
|
|
|
|
sparc_file_end (void)
|
|
|
|
|
{
|
|
|
|
|
/* If we need to emit the special GOT helper function, do so now. */
|
|
|
|
|
- if (got_helper_needed)
|
|
|
|
|
+ if (got_helper_rtx)
|
|
|
|
|
{
|
|
|
|
|
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
|
2021-04-11 11:47:36 +02:00
|
|
|
|
@@ -12546,22 +12525,17 @@ sparc_file_end (void)
|
2021-01-21 00:02:34 +01:00
|
|
|
|
#ifdef DWARF2_UNWIND_INFO
|
|
|
|
|
do_cfi = dwarf2out_do_cfi_asm ();
|
|
|
|
|
if (do_cfi)
|
|
|
|
|
- output_asm_insn (".cfi_startproc", NULL);
|
|
|
|
|
+ fprintf (asm_out_file, "\t.cfi_startproc\n");
|
|
|
|
|
#endif
|
|
|
|
|
if (flag_delayed_branch)
|
|
|
|
|
- {
|
|
|
|
|
- output_asm_insn ("jmp\t%%o7+8", NULL);
|
|
|
|
|
- output_asm_insn (" add\t%%o7, %0, %0", &got_register_rtx);
|
|
|
|
|
- }
|
|
|
|
|
+ fprintf (asm_out_file, "\tjmp\t%%o7+8\n\t add\t%%o7, %s, %s\n",
|
|
|
|
|
+ reg_name, reg_name);
|
|
|
|
|
else
|
|
|
|
|
- {
|
|
|
|
|
- output_asm_insn ("add\t%%o7, %0, %0", &got_register_rtx);
|
|
|
|
|
- output_asm_insn ("jmp\t%%o7+8", NULL);
|
|
|
|
|
- output_asm_insn (" nop", NULL);
|
|
|
|
|
- }
|
|
|
|
|
+ fprintf (asm_out_file, "\tadd\t%%o7, %s, %s\n\tjmp\t%%o7+8\n\t nop\n",
|
|
|
|
|
+ reg_name, reg_name);
|
|
|
|
|
#ifdef DWARF2_UNWIND_INFO
|
|
|
|
|
if (do_cfi)
|
|
|
|
|
- output_asm_insn (".cfi_endproc", NULL);
|
|
|
|
|
+ fprintf (asm_out_file, "\t.cfi_endproc\n");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-11 11:47:36 +02:00
|
|
|
|
@@ -13056,10 +13030,7 @@ sparc_init_pic_reg (void)
|
2021-01-21 00:02:34 +01:00
|
|
|
|
edge entry_edge;
|
|
|
|
|
rtx_insn *seq;
|
|
|
|
|
|
|
|
|
|
- /* 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))
|
|
|
|
|
+ if (!crtl->uses_pic_offset_table)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
start_sequence ();
|
|
|
|
|
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
|
2021-04-11 11:47:36 +02:00
|
|
|
|
index 6e9ccb4ecfd..8fb0fa11aed 100644
|
2021-01-21 00:02:34 +01:00
|
|
|
|
--- a/gcc/config/sparc/sparc.md
|
|
|
|
|
+++ b/gcc/config/sparc/sparc.md
|
2021-04-11 11:47:36 +02:00
|
|
|
|
@@ -1601,7 +1601,10 @@
|
2021-01-21 00:02:34 +01:00
|
|
|
|
(clobber (reg:P O7_REG))]
|
|
|
|
|
"REGNO (operands[0]) == INTVAL (operands[3])"
|
|
|
|
|
{
|
|
|
|
|
- return output_load_pcrel_sym (operands);
|
|
|
|
|
+ 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";
|
|
|
|
|
}
|
|
|
|
|
[(set (attr "type") (const_string "multi"))
|
|
|
|
|
(set (attr "length")
|
|
|
|
|
diff --git a/gcc/testsuite/gcc.c-torture/compile/20191108-1.c b/gcc/testsuite/gcc.c-torture/compile/20191108-1.c
|
|
|
|
|
deleted file mode 100644
|
|
|
|
|
index 7929751bb06..00000000000
|
|
|
|
|
--- a/gcc/testsuite/gcc.c-torture/compile/20191108-1.c
|
|
|
|
|
+++ /dev/null
|
|
|
|
|
@@ -1,14 +0,0 @@
|
|
|
|
|
-/* 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;
|
|
|
|
|
-}
|
|
|
|
|
diff --git a/gcc/testsuite/gcc.target/sparc/overflow-3.c b/gcc/testsuite/gcc.target/sparc/overflow-3.c
|
|
|
|
|
index 52d6ab2b688..86dddfb09e6 100644
|
|
|
|
|
--- a/gcc/testsuite/gcc.target/sparc/overflow-3.c
|
|
|
|
|
+++ b/gcc/testsuite/gcc.target/sparc/overflow-3.c
|
|
|
|
|
@@ -1,6 +1,6 @@
|
|
|
|
|
/* { dg-do compile } */
|
|
|
|
|
/* { dg-require-effective-target lp64 } */
|
|
|
|
|
-/* { dg-options "-O -fno-pie" } */
|
|
|
|
|
+/* { dg-options "-O" } */
|
|
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
diff --git a/gcc/testsuite/gcc.target/sparc/overflow-4.c b/gcc/testsuite/gcc.target/sparc/overflow-4.c
|
|
|
|
|
index c6121b958c3..019feee335c 100644
|
|
|
|
|
--- a/gcc/testsuite/gcc.target/sparc/overflow-4.c
|
|
|
|
|
+++ b/gcc/testsuite/gcc.target/sparc/overflow-4.c
|
|
|
|
|
@@ -1,6 +1,6 @@
|
|
|
|
|
/* { dg-do compile } */
|
|
|
|
|
/* { dg-require-effective-target lp64 } */
|
|
|
|
|
-/* { dg-options "-O -fno-pie -mno-vis3 -mno-vis4" } */
|
|
|
|
|
+/* { dg-options "-O -mno-vis3 -mno-vis4" } */
|
|
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
diff --git a/gcc/testsuite/gcc.target/sparc/overflow-5.c b/gcc/testsuite/gcc.target/sparc/overflow-5.c
|
|
|
|
|
index f00283f6e7b..67d4ac38095 100644
|
|
|
|
|
--- a/gcc/testsuite/gcc.target/sparc/overflow-5.c
|
|
|
|
|
+++ b/gcc/testsuite/gcc.target/sparc/overflow-5.c
|
|
|
|
|
@@ -1,6 +1,6 @@
|
|
|
|
|
/* { dg-do compile } */
|
|
|
|
|
/* { dg-require-effective-target lp64 } */
|
|
|
|
|
-/* { dg-options "-O -fno-pie -mvis3" } */
|
|
|
|
|
+/* { dg-options "-O -mvis3" } */
|
|
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
--
|
2021-04-11 11:47:36 +02:00
|
|
|
|
2.30.2
|
2021-01-21 00:02:34 +01:00
|
|
|
|
|