This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Don't keep notes about obliterated libcall sequence


When combine deleted a hand-crafted libcall sequence, such as the one
generated by SH4's `mulsi3', distribute_notes() ended up moving the
REG_RETVAL note to the insn before the deleted sequence, and the
REG_LIBCALL note to the insn after it.  This would cause
propagate_one_block() to enter an endless loop because
propagate_one_insn() would return, when given the insn with the dead
RETVAL, the insn before the LIBCALL.  Then, since
propagate_one_block() moves backwards, it ends up again in the insn
with the RETVAL, and so on.

Unfortunately, I don't have a testcase that exposes the bug in the
current CVS tree.  C's functions-as-trees hide this particular
instance of the bug because of constant folding, and I couldn't find
any testcase that would cause an endless loop in the current tree :-(

This patch arranges for the notes to be removed when they point at the
insn that is being removed.  Ok to install?

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* combine.c (distribute_notes): Discard REG_LIBCALL and REG_RETVAL
	when deleting libcall sequence collapsed to a single instruction.

Index: gcc/combine.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/combine.c,v
retrieving revision 1.158
diff -u -p -r1.158 combine.c
--- gcc/combine.c 2000/10/20 17:28:28 1.158
+++ gcc/combine.c 2000/10/23 06:53:18
@@ -12239,6 +12239,10 @@ distribute_notes (notes, from_insn, i3, 
 	      place = prev_real_insn (from_insn);
 	      if (tem && place)
 		XEXP (tem, 0) = place;
+	      /* If we're deleting the last remaining instruction of a
+		 libcall sequence, don't add the notes.  */
+	      else if (XEXP (note, 0) == from_insn)
+		tem = place = 0;
 	    }
 	  break;
 
@@ -12252,6 +12256,10 @@ distribute_notes (notes, from_insn, i3, 
 	      place = next_real_insn (from_insn);
 	      if (tem && place)
 		XEXP (tem, 0) = place;
+	      /* If we're deleting the last remaining instruction of a
+		 libcall sequence, don't add the notes.  */
+	      else if (XEXP (note, 0) == from_insn)
+		tem = place = 0;
 	    }
 	  break;
 

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist    *Please* write to mailing lists, not to me

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]