1From bb9b71752267444b4360442b89129bfc0ae938d3 Mon Sep 17 00:00:00 2001
2From: Romain Naour <romain.naour@gmail.com>
3Date: Wed, 20 Jan 2021 23:06:07 +0100
4Subject: [PATCH] Revert "re PR target/92095 (internal error with -O1
5 -mcpu=niagara2 -fPIE)"
6
7This reverts commit 3fcce773f0f914c0499b130c6e9efa0e45ee54a0.
8
9Building the Buildroot defconfig qemu_sparc_ss10_defconfig using
10gcc 8.4, 9.3 and 10 produce a broken rootfs that trigger illegal
11instruction messages.
12
13gcc 8.3, 9.2 are the latest working gcc version.
14git bisect between gcc 8.4 and 8.4 allowed to identify
15the commit that introcuce the regression.
16
17Reverting this patch allowed to produce a working rootfs.
18
19Signed-off-by: Romain Naour <romain.naour@gmail.com>
20Cc: Eric Botcazou <ebotcazou@gcc.gnu.org>
21---
22 gcc/config/sparc/sparc-protos.h               |   1 -
23 gcc/config/sparc/sparc.c                      | 121 +++++++-----------
24 gcc/config/sparc/sparc.md                     |   5 +-
25 .../gcc.c-torture/compile/20191108-1.c        |  14 --
26 gcc/testsuite/gcc.target/sparc/overflow-3.c   |   2 +-
27 gcc/testsuite/gcc.target/sparc/overflow-4.c   |   2 +-
28 gcc/testsuite/gcc.target/sparc/overflow-5.c   |   2 +-
29 7 files changed, 53 insertions(+), 94 deletions(-)
30 delete mode 100644 gcc/testsuite/gcc.c-torture/compile/20191108-1.c
31
32diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
33index b3f73c2f2bf..71a067e871c 100644
34--- a/gcc/config/sparc/sparc-protos.h
35+++ b/gcc/config/sparc/sparc-protos.h
36@@ -69,7 +69,6 @@ extern void sparc_split_reg_mem (rtx, rtx, machine_mode);
37 extern void sparc_split_mem_reg (rtx, rtx, machine_mode);
38 extern int sparc_split_reg_reg_legitimate (rtx, rtx);
39 extern void sparc_split_reg_reg (rtx, rtx, machine_mode);
40-extern const char *output_load_pcrel_sym (rtx *);
41 extern const char *output_ubranch (rtx, rtx_insn *);
42 extern const char *output_cbranch (rtx, rtx, int, int, int, rtx_insn *);
43 extern const char *output_return (rtx_insn *);
44diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
45index 73032d33596..db1b428db90 100644
46--- a/gcc/config/sparc/sparc.c
47+++ b/gcc/config/sparc/sparc.c
48@@ -4200,6 +4200,13 @@ eligible_for_sibcall_delay (rtx_insn *trial)
49 static bool
50 sparc_cannot_force_const_mem (machine_mode mode, rtx x)
51 {
52+  /* After IRA has run in PIC mode, it is too late to put anything into the
53+     constant pool if the PIC register hasn't already been initialized.  */
54+  if ((lra_in_progress || reload_in_progress)
55+      && flag_pic
56+      && !crtl->uses_pic_offset_table)
57+    return true;
58+
59   switch (GET_CODE (x))
60     {
61     case CONST_INT:
62@@ -4235,11 +4242,9 @@ sparc_cannot_force_const_mem (machine_mode mode, rtx x)
63 }
64
65 /* Global Offset Table support.  */
66-static GTY(()) rtx got_symbol_rtx = NULL_RTX;
67-static GTY(()) rtx got_register_rtx = NULL_RTX;
68 static GTY(()) rtx got_helper_rtx = NULL_RTX;
69-
70-static GTY(()) bool got_helper_needed = false;
71+static GTY(()) rtx got_register_rtx = NULL_RTX;
72+static GTY(()) rtx got_symbol_rtx = NULL_RTX;
73
74 /* Return the SYMBOL_REF for the Global Offset Table.  */
75
76@@ -4252,6 +4257,27 @@ sparc_got (void)
77   return got_symbol_rtx;
78 }
79
80+#ifdef HAVE_GAS_HIDDEN
81+# define USE_HIDDEN_LINKONCE 1
82+#else
83+# define USE_HIDDEN_LINKONCE 0
84+#endif
85+
86+static void
87+get_pc_thunk_name (char name[32], unsigned int regno)
88+{
89+  const char *reg_name = reg_names[regno];
90+
91+  /* Skip the leading '%' as that cannot be used in a
92+     symbol name.  */
93+  reg_name += 1;
94+
95+  if (USE_HIDDEN_LINKONCE)
96+    sprintf (name, "__sparc_get_pc_thunk.%s", reg_name);
97+  else
98+    ASM_GENERATE_INTERNAL_LABEL (name, "LADDPC", regno);
99+}
100+
101 /* Wrapper around the load_pcrel_sym{si,di} patterns.  */
102
103 static rtx
104@@ -4271,78 +4297,30 @@ gen_load_pcrel_sym (rtx op0, rtx op1, rtx op2)
105   return insn;
106 }
107
108-/* Output the load_pcrel_sym{si,di} patterns.  */
109-
110-const char *
111-output_load_pcrel_sym (rtx *operands)
112-{
113-  if (flag_delayed_branch)
114-    {
115-      output_asm_insn ("sethi\t%%hi(%a1-4), %0", operands);
116-      output_asm_insn ("call\t%a2", operands);
117-      output_asm_insn (" add\t%0, %%lo(%a1+4), %0", operands);
118-    }
119-  else
120-    {
121-      output_asm_insn ("sethi\t%%hi(%a1-8), %0", operands);
122-      output_asm_insn ("add\t%0, %%lo(%a1-4), %0", operands);
123-      output_asm_insn ("call\t%a2", operands);
124-      output_asm_insn (" nop", NULL);
125-    }
126-
127-  if (operands[2] == got_helper_rtx)
128-    got_helper_needed = true;
129-
130-  return "";
131-}
132-
133-#ifdef HAVE_GAS_HIDDEN
134-# define USE_HIDDEN_LINKONCE 1
135-#else
136-# define USE_HIDDEN_LINKONCE 0
137-#endif
138-
139 /* Emit code to load the GOT register.  */
140
141 void
142 load_got_register (void)
143 {
144-  rtx insn;
145+  if (!got_register_rtx)
146+    got_register_rtx = gen_rtx_REG (Pmode, GLOBAL_OFFSET_TABLE_REGNUM);
147
148   if (TARGET_VXWORKS_RTP)
149-    {
150-      if (!got_register_rtx)
151-	got_register_rtx = pic_offset_table_rtx;
152-
153-      insn = gen_vxworks_load_got ();
154-    }
155+    emit_insn (gen_vxworks_load_got ());
156   else
157     {
158-      if (!got_register_rtx)
159-	got_register_rtx = gen_rtx_REG (Pmode, GLOBAL_OFFSET_TABLE_REGNUM);
160-
161       /* The GOT symbol is subject to a PC-relative relocation so we need a
162 	 helper function to add the PC value and thus get the final value.  */
163       if (!got_helper_rtx)
164 	{
165 	  char name[32];
166-
167-	  /* Skip the leading '%' as that cannot be used in a symbol name.  */
168-	  if (USE_HIDDEN_LINKONCE)
169-	    sprintf (name, "__sparc_get_pc_thunk.%s",
170-		     reg_names[REGNO (got_register_rtx)] + 1);
171-	  else
172-	    ASM_GENERATE_INTERNAL_LABEL (name, "LADDPC",
173-					 REGNO (got_register_rtx));
174-
175+	  get_pc_thunk_name (name, GLOBAL_OFFSET_TABLE_REGNUM);
176 	  got_helper_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
177 	}
178
179-      insn
180-	= gen_load_pcrel_sym (got_register_rtx, sparc_got (), got_helper_rtx);
181+      emit_insn (gen_load_pcrel_sym (got_register_rtx, sparc_got (),
182+				     got_helper_rtx));
183     }
184-
185-  emit_insn (insn);
186 }
187
188 /* Ensure that we are not using patterns that are not OK with PIC.  */
189@@ -5494,7 +5472,7 @@ save_local_or_in_reg_p (unsigned int regno, int leaf_function)
190     return true;
191
192   /* GOT register (%l7) if needed.  */
193-  if (got_register_rtx && regno == REGNO (got_register_rtx))
194+  if (regno == GLOBAL_OFFSET_TABLE_REGNUM && got_register_rtx)
195     return true;
196
197   /* If the function accesses prior frames, the frame pointer and the return
198@@ -12475,9 +12453,10 @@ static void
199 sparc_file_end (void)
200 {
201   /* If we need to emit the special GOT helper function, do so now.  */
202-  if (got_helper_needed)
203+  if (got_helper_rtx)
204     {
205       const char *name = XSTR (got_helper_rtx, 0);
206+      const char *reg_name = reg_names[GLOBAL_OFFSET_TABLE_REGNUM];
207 #ifdef DWARF2_UNWIND_INFO
208       bool do_cfi;
209 #endif
210@@ -12514,22 +12493,17 @@ sparc_file_end (void)
211 #ifdef DWARF2_UNWIND_INFO
212       do_cfi = dwarf2out_do_cfi_asm ();
213       if (do_cfi)
214-	output_asm_insn (".cfi_startproc", NULL);
215+	fprintf (asm_out_file, "\t.cfi_startproc\n");
216 #endif
217       if (flag_delayed_branch)
218-	{
219-	  output_asm_insn ("jmp\t%%o7+8", NULL);
220-	  output_asm_insn (" add\t%%o7, %0, %0", &got_register_rtx);
221-	}
222+	fprintf (asm_out_file, "\tjmp\t%%o7+8\n\t add\t%%o7, %s, %s\n",
223+		 reg_name, reg_name);
224       else
225-	{
226-	  output_asm_insn ("add\t%%o7, %0, %0", &got_register_rtx);
227-	  output_asm_insn ("jmp\t%%o7+8", NULL);
228-	  output_asm_insn (" nop", NULL);
229-	}
230+	fprintf (asm_out_file, "\tadd\t%%o7, %s, %s\n\tjmp\t%%o7+8\n\t nop\n",
231+		 reg_name, reg_name);
232 #ifdef DWARF2_UNWIND_INFO
233       if (do_cfi)
234-	output_asm_insn (".cfi_endproc", NULL);
235+	fprintf (asm_out_file, "\t.cfi_endproc\n");
236 #endif
237     }
238
239@@ -13035,10 +13009,7 @@ sparc_init_pic_reg (void)
240   edge entry_edge;
241   rtx_insn *seq;
242
243-  /* In PIC mode, we need to always initialize the PIC register if optimization
244-     is enabled, because we are called from IRA and LRA may later force things
245-     to the constant pool for optimization purposes.  */
246-  if (!flag_pic || (!crtl->uses_pic_offset_table && !optimize))
247+  if (!crtl->uses_pic_offset_table)
248     return;
249
250   start_sequence ();
251diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
252index 468e2cc5d3b..25134bd1148 100644
253--- a/gcc/config/sparc/sparc.md
254+++ b/gcc/config/sparc/sparc.md
255@@ -1601,7 +1601,10 @@
256    (clobber (reg:P O7_REG))]
257   "REGNO (operands[0]) == INTVAL (operands[3])"
258 {
259-  return output_load_pcrel_sym (operands);
260+  if (flag_delayed_branch)
261+    return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
262+  else
263+    return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
264 }
265   [(set (attr "type") (const_string "multi"))
266    (set (attr "length")
267diff --git a/gcc/testsuite/gcc.c-torture/compile/20191108-1.c b/gcc/testsuite/gcc.c-torture/compile/20191108-1.c
268deleted file mode 100644
269index 7929751bb06..00000000000
270--- a/gcc/testsuite/gcc.c-torture/compile/20191108-1.c
271+++ /dev/null
272@@ -1,14 +0,0 @@
273-/* PR target/92095 */
274-/* Testcase by Sergei Trofimovich <slyfox@inbox.ru> */
275-
276-typedef union {
277-  double a;
278-  int b[2];
279-} c;
280-
281-double d(int e)
282-{
283-  c f;
284-  (&f)->b[0] = 15728640;
285-  return e ? -(&f)->a : (&f)->a;
286-}
287diff --git a/gcc/testsuite/gcc.target/sparc/overflow-3.c b/gcc/testsuite/gcc.target/sparc/overflow-3.c
288index 18253bb6e5e..8cb24f52f7b 100644
289--- a/gcc/testsuite/gcc.target/sparc/overflow-3.c
290+++ b/gcc/testsuite/gcc.target/sparc/overflow-3.c
291@@ -1,5 +1,5 @@
292 /* { dg-do compile } */
293-/* { dg-options "-O -fno-pie" } */
294+/* { dg-options "-O" } */
295 /* { dg-require-effective-target lp64 } */
296
297 #include <stdbool.h>
298diff --git a/gcc/testsuite/gcc.target/sparc/overflow-4.c b/gcc/testsuite/gcc.target/sparc/overflow-4.c
299index fb30877efb9..868edea2b9e 100644
300--- a/gcc/testsuite/gcc.target/sparc/overflow-4.c
301+++ b/gcc/testsuite/gcc.target/sparc/overflow-4.c
302@@ -1,5 +1,5 @@
303 /* { dg-do compile } */
304-/* { dg-options "-O -fno-pie -mno-vis3" } */
305+/* { dg-options "-O -mno-vis3" } */
306 /* { dg-require-effective-target lp64 } */
307
308 #include <stdbool.h>
309diff --git a/gcc/testsuite/gcc.target/sparc/overflow-5.c b/gcc/testsuite/gcc.target/sparc/overflow-5.c
310index 509d957715d..501ce04f7a1 100644
311--- a/gcc/testsuite/gcc.target/sparc/overflow-5.c
312+++ b/gcc/testsuite/gcc.target/sparc/overflow-5.c
313@@ -1,5 +1,5 @@
314 /* { dg-do compile } */
315-/* { dg-options "-O -fno-pie -mvis3" } */
316+/* { dg-options "-O -mvis3" } */
317 /* { dg-require-effective-target lp64 } */
318
319 #include <stdbool.h>
320--
3212.25.4
322
323