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