public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Patch] Fix bug for frame instructions in annulled delay slots
@ 2015-12-07 18:54 Steve Ellcey 
  2015-12-07 19:28 ` Bernd Schmidt
  0 siblings, 1 reply; 8+ messages in thread
From: Steve Ellcey  @ 2015-12-07 18:54 UTC (permalink / raw)
  To: gcc-patches

While doing more testing of the MIPS frame header optimization I checked
in earlier, I found I could not build the elf toolchain when I turned the
optimization on by default.  This is because GCC was putting a frame related
instruction (the save of the return address) into an annulled delay slot.
This only happens when the function prologue is moved after a branch by the
shrink wrap optimization and it caused create_cfi_notes to abort because the
code that generates the CFI information cannot handle stack related annulled
instructions.

This never occurred when I did my testing with the linux toolchain because
I did not use -Os (which caused the use of instructions with annulled delay
slots) and because -O2 does more inlining than -Os which meant there were
fewer places where the return address could be saved in the callers frame
header without the callee having to allocate its own stack space.

The fix for this is not in mips specific code but in reorg.c where we
restrict GCC from putting any frame related instructions into annulled
delay slots.  There was already code in reorg.c to prevent frame related
instructions from going into normal delay slots but that code did not seem
to cover all the unnulled delay slot situations.  This patch extends the
code to not put frame related instructions into annulled delay slots.

Tested on MIPS with linux and elf toolchain builds and testsuite runs.

OK to checkin?

Steve Ellcey
sellcey@imgtec.com


2015-12-07  Steve Ellcey  <sellcey@imgtec.com>

	* reorg.c (optimize_skip): Do not put frame related instructions
	in annulled delay slots.
	(steal_delay_list_from_target): Ditto.
	(fill_slots_from_thread): Ditto.


diff --git a/gcc/reorg.c b/gcc/reorg.c
index cc68d6b..bab5f49 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -739,6 +739,7 @@ optimize_skip (rtx_jump_insn *insn, vec<rtx_insn *> *delay_list)
       || recog_memoized (trial) < 0
       || (! eligible_for_annul_false (insn, 0, trial, flags)
 	  && ! eligible_for_annul_true (insn, 0, trial, flags))
+      || RTX_FRAME_RELATED_P (trial)
       || can_throw_internal (trial))
     return;
 
@@ -1126,7 +1127,13 @@ steal_delay_list_from_target (rtx_insn *insn, rtx condition, rtx_sequence *seq,
 					      trial, flags)))
 	{
 	  if (must_annul)
-	    used_annul = 1;
+	    {
+	      /* Frame related instructions cannot go into annulled delay
+		 slots, it messes up the dwarf info.  */
+	      if (RTX_FRAME_RELATED_P (trial))
+		return;
+	      used_annul = 1;
+	    }
 	  rtx_insn *temp = copy_delay_slot_insn (trial);
 	  INSN_FROM_TARGET_P (temp) = 1;
 	  add_to_delay_list (temp, &new_delay_list);
@@ -2464,9 +2471,9 @@ fill_slots_from_thread (rtx_jump_insn *insn, rtx condition,
 	      if (eligible_for_delay (insn, *pslots_filled, trial, flags))
 		goto winner;
 	    }
-	  else if (0
-		   || (ANNUL_IFTRUE_SLOTS && ! thread_if_true)
-		   || (ANNUL_IFFALSE_SLOTS && thread_if_true))
+	  else if (!RTX_FRAME_RELATED_P (trial) \
+		   && ((ANNUL_IFTRUE_SLOTS && ! thread_if_true)
+		        || (ANNUL_IFFALSE_SLOTS && thread_if_true)))
 	    {
 	      old_trial = trial;
 	      trial = try_split (pat, trial, 0);



2015-12-07  Steve Ellcey  <sellcey@imgtec.com>

	* gcc.target/mips/wrap-delay.c: New test.


diff --git a/gcc/testsuite/gcc.target/mips/wrap-delay.c b/gcc/testsuite/gcc.target/mips/wrap-delay.c
index e69de29..1332a68 100644
--- a/gcc/testsuite/gcc.target/mips/wrap-delay.c
+++ b/gcc/testsuite/gcc.target/mips/wrap-delay.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-g -mframe-header-opt -mbranch-likely" } */
+
+/* GCC was generating an ICE with the above options and -Os because
+   it was putting the save of $31 in two annulled delay slots but
+   there was only one restore since only one of the two saves could be
+   executed.  This was correct code but it confused dwarf2cfi and
+   caused it to ICE when using the -g option.  */
+
+
+enum demangle_component_type
+{
+	DEMANGLE_COMPONENT_TRINARY_ARG2,
+};
+struct demangle_component
+{
+  enum demangle_component_type type;
+};
+struct d_info
+{
+  int next_comp;
+  int num_comps;
+};
+struct demangle_component * d_make_empty (struct d_info *di)
+{
+  if (di->next_comp >= di->num_comps) return ((void *)0);
+  ++di->next_comp;
+}
+struct demangle_component *d_make_comp (
+	struct d_info *di,
+	enum demangle_component_type type,
+	struct demangle_component *left)
+{
+  struct demangle_component *p;
+  switch (type)
+    {
+    case DEMANGLE_COMPONENT_TRINARY_ARG2:
+      if (left == ((void *)0)) return ((void *)0);
+    }
+  p = d_make_empty (di);
+  p->type = type;
+}

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-12-08 22:54 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-07 18:54 [Patch] Fix bug for frame instructions in annulled delay slots Steve Ellcey 
2015-12-07 19:28 ` Bernd Schmidt
2015-12-07 19:30   ` Jeff Law
2015-12-07 21:19     ` Steve Ellcey
2015-12-08 22:54       ` Jeff Law
2015-12-07 19:44   ` Steve Ellcey
2015-12-07 19:59     ` Bernd Schmidt
2015-12-07 20:43       ` Steve Ellcey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).