diff mbox

(Still) ICE for cris-elf at r214710

Message ID 1409311619.31600.11.camel@surprise
State New
Headers show

Commit Message

David Malcolm Aug. 29, 2014, 11:26 a.m. UTC
On Fri, 2014-08-29 at 06:13 +0200, Hans-Peter Nilsson wrote:
> Sorry for the context-less mail but I didn't find a proper
> obvious gcc-patches-message to reply to.  (Also, I can't log
> into bugzilla because to enter a PR as there appears to have
> been some SSL changes such that my old firefox and gcc.gnu.org
> can no longer agree on a cipher or something.)  But, since
> r214690 and at up to and including r214714 (HEAD as of this
> writing), a build for cris-elf fails on trunk as follows:
> 
> /tmp/hpautotest-gcc1/cris-elf/gccobj/./gcc/xgcc -B/tmp/hpautotest-gcc1/cris-elf/gccobj/./gcc/ -nostdinc -B/tmp/hpautotest-gcc1/cris-elf/gccobj/cris-elf/newlib/ -isystem /tmp/hpautotest-gcc1/cris-elf/gccobj/cris-elf/newlib/targ-include -isystem /tmp/hpautotest-gcc1/gcc/newlib/libc/include -B/tmp/hpautotest-gcc1/cris-elf/gccobj/cris-elf/libgloss/cris -L/tmp/hpautotest-gcc1/cris-elf/gccobj/cris-elf/libgloss/libnosys -L/tmp/hpautotest-gcc1/gcc/libgloss/cris -B/tmp/hpautotest-gcc1/cris-elf/pre/cris-elf/bin/ -B/tmp/hpautotest-gcc1/cris-elf/pre/cris-elf/lib/ -isystem /tmp/hpautotest-gcc1/cris-elf/pre/cris-elf/include -isystem /tmp/hpautotest-gcc1/cris-elf/pre/cris-elf/sys-include    -g -O2 -march=v8 -mbest-lib-options -O2  -g -O2 -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE  -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition  -isystem ./include   -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -Dinhibit_libc  -I. -I. -I../../.././!
 gcc
>   -I/tmp/
>  hpautotest-gcc1/gcc/libgcc -I/tmp/hpautotest-gcc1/gcc/libgcc/. -I/tmp/hpautotest-gcc1/gcc/libgcc/../gcc -I/tmp/hpautotest-gcc1/gcc/libgcc/../include  -DHAVE_CC_TLS -DUSE_EMUTLS -o _lshrdi3.o -MT _lshrdi3.o -MD -MP -MF _lshrdi3.dep -DL_lshrdi3 -c /tmp/hpautotest-gcc1/gcc/libgcc/libgcc2.c -fvisibility=hidden -DHIDE_EXPORTS
> /tmp/hpautotest-gcc1/gcc/libgcc/libgcc2.c: In function '__lshrdi3':
> /tmp/hpautotest-gcc1/gcc/libgcc/libgcc2.c:426:1: internal compiler error: in safe_as_a, at is-a.h:205
>  }
>  ^
> 0x9119c2 safe_as_a<rtx_insn*, rtx_def>
>         /tmp/hpautotest-gcc1/gcc/gcc/is-a.h:205
> 0x9119c2 JUMP_LABEL_AS_INSN
>         /tmp/hpautotest-gcc1/gcc/gcc/rtl.h:1663
> 0x9119c2 find_dead_or_set_registers
>         /tmp/hpautotest-gcc1/gcc/gcc/resource.c:500
> 0x912408 mark_target_live_regs(rtx_insn*, rtx_insn*, resources*)
>         /tmp/hpautotest-gcc1/gcc/gcc/resource.c:1115
> 0x90cb4b fill_slots_from_thread
>         /tmp/hpautotest-gcc1/gcc/gcc/reorg.c:2404
> 0x90ff45 fill_eager_delay_slots
>         /tmp/hpautotest-gcc1/gcc/gcc/reorg.c:2933
> 0x90ff45 dbr_schedule
>         /tmp/hpautotest-gcc1/gcc/gcc/reorg.c:3742
> 0x9108ef rest_of_handle_delay_slots
>         /tmp/hpautotest-gcc1/gcc/gcc/reorg.c:3885
> 0x9108ef execute
>         /tmp/hpautotest-gcc1/gcc/gcc/reorg.c:3916
> Please submit a full bug report,
> with preprocessed source if appropriate.
> Please include the complete backtrace with any bug report.
> See <http://gcc.gnu.org/bugs.html> for instructions.
> make[4]: *** [_lshrdi3.o] Error 1
> 
> Use "./cc1 -fpreprocessed this.i -O2" to repeat.
> 
> struct DWstruct {int low, high;};
> 
> typedef union
> {
>   struct DWstruct s;
>   long long ll;
> } DWunion;
> 
> long long
> __lshrdi3 (long long u, int b)
> {
>   if (b == 0)
>     return u;
> 
>   const DWunion uu = {.ll = u};
>   const int bm = (4 * (8)) - b;
>   DWunion w;
> 
>   if (bm <= 0)
>     {
>       w.s.high = 0;
>       w.s.low = (unsigned int) uu.s.high >> -bm;
>     }
>   else
>     {
>       const unsigned int carries = (unsigned int) uu.s.high << bm;
> 
>       w.s.high = (unsigned int) uu.s.high >> b;
>       w.s.low = ((unsigned int) uu.s.low >> b) | carries;
>     }
> 
>   return w.ll;
> }

Sorry about this.

Looks like I introduced this bug in r214693 (aka patch #225).

The issue is within resource.c:
499			{
500			  next = JUMP_LABEL_AS_INSN (this_jump_insn);
501			  if (ANY_RETURN_P (next))
502			    next = NULL;

where "next" is an rtx_insn *, but the JUMP_LABEL of this_jump_insn is a
RETURN, rather than an insn (several such issues in that commit).

Patch attached, which fixes the above testcase; bootstrap in progress:

gcc/
	* resource.h (mark_target_live_regs): Undo erroneous conversion
	of second param of r214693, converting it back from rtx_insn * to
	rtx, since it could be a RETURN.

	* resource.c (find_dead_or_set_registers): Similarly, convert
	param "jump_target" back from an rtx_insn ** to an rtx *, as we
	could be writing back a RETURN.  Rename local rtx_insn * "next" to
	"next_insn", and introduce "lab_or_return" as a local rtx,
	handling the case where JUMP_LABEL (this_jump_insn) is a RETURN.
	(mark_target_live_regs): Undo erroneous conversion
	of second param of r214693, converting it back from rtx_insn * to
	rtx, since it could be a RETURN.  Rename it from "target" to
	"target_maybe_return", reintroducing the name "target" as a local
	rtx_insn * with a checked cast, after we've handled the case of
	ANY_RETURN_P.

Comments

David Malcolm Aug. 29, 2014, 11:40 a.m. UTC | #1
On Fri, 2014-08-29 at 07:26 -0400, David Malcolm wrote:
> On Fri, 2014-08-29 at 06:13 +0200, Hans-Peter Nilsson wrote:
> > Sorry for the context-less mail but I didn't find a proper
> > obvious gcc-patches-message to reply to.  (Also, I can't log
> > into bugzilla because to enter a PR as there appears to have
> > been some SSL changes such that my old firefox and gcc.gnu.org
> > can no longer agree on a cipher or something.)  But, since
> > r214690 and at up to and including r214714 (HEAD as of this
> > writing), a build for cris-elf fails on trunk as follows:
> > 
> > /tmp/hpautotest-gcc1/cris-elf/gccobj/./gcc/xgcc -B/tmp/hpautotest-gcc1/cris-elf/gccobj/./gcc/ -nostdinc -B/tmp/hpautotest-gcc1/cris-elf/gccobj/cris-elf/newlib/ -isystem /tmp/hpautotest-gcc1/cris-elf/gccobj/cris-elf/newlib/targ-include -isystem /tmp/hpautotest-gcc1/gcc/newlib/libc/include -B/tmp/hpautotest-gcc1/cris-elf/gccobj/cris-elf/libgloss/cris -L/tmp/hpautotest-gcc1/cris-elf/gccobj/cris-elf/libgloss/libnosys -L/tmp/hpautotest-gcc1/gcc/libgloss/cris -B/tmp/hpautotest-gcc1/cris-elf/pre/cris-elf/bin/ -B/tmp/hpautotest-gcc1/cris-elf/pre/cris-elf/lib/ -isystem /tmp/hpautotest-gcc1/cris-elf/pre/cris-elf/include -isystem /tmp/hpautotest-gcc1/cris-elf/pre/cris-elf/sys-include    -g -O2 -march=v8 -mbest-lib-options -O2  -g -O2 -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE  -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition  -isystem ./include   -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -Dinhibit_libc  -I. -I. -I../../../!
 ./!
>  gcc
> >   -I/tmp/
> >  hpautotest-gcc1/gcc/libgcc -I/tmp/hpautotest-gcc1/gcc/libgcc/. -I/tmp/hpautotest-gcc1/gcc/libgcc/../gcc -I/tmp/hpautotest-gcc1/gcc/libgcc/../include  -DHAVE_CC_TLS -DUSE_EMUTLS -o _lshrdi3.o -MT _lshrdi3.o -MD -MP -MF _lshrdi3.dep -DL_lshrdi3 -c /tmp/hpautotest-gcc1/gcc/libgcc/libgcc2.c -fvisibility=hidden -DHIDE_EXPORTS
> > /tmp/hpautotest-gcc1/gcc/libgcc/libgcc2.c: In function '__lshrdi3':
> > /tmp/hpautotest-gcc1/gcc/libgcc/libgcc2.c:426:1: internal compiler error: in safe_as_a, at is-a.h:205
> >  }
> >  ^
> > 0x9119c2 safe_as_a<rtx_insn*, rtx_def>
> >         /tmp/hpautotest-gcc1/gcc/gcc/is-a.h:205
> > 0x9119c2 JUMP_LABEL_AS_INSN
> >         /tmp/hpautotest-gcc1/gcc/gcc/rtl.h:1663
> > 0x9119c2 find_dead_or_set_registers
> >         /tmp/hpautotest-gcc1/gcc/gcc/resource.c:500
> > 0x912408 mark_target_live_regs(rtx_insn*, rtx_insn*, resources*)
> >         /tmp/hpautotest-gcc1/gcc/gcc/resource.c:1115
> > 0x90cb4b fill_slots_from_thread
> >         /tmp/hpautotest-gcc1/gcc/gcc/reorg.c:2404
> > 0x90ff45 fill_eager_delay_slots
> >         /tmp/hpautotest-gcc1/gcc/gcc/reorg.c:2933
> > 0x90ff45 dbr_schedule
> >         /tmp/hpautotest-gcc1/gcc/gcc/reorg.c:3742
> > 0x9108ef rest_of_handle_delay_slots
> >         /tmp/hpautotest-gcc1/gcc/gcc/reorg.c:3885
> > 0x9108ef execute
> >         /tmp/hpautotest-gcc1/gcc/gcc/reorg.c:3916
> > Please submit a full bug report,
> > with preprocessed source if appropriate.
> > Please include the complete backtrace with any bug report.
> > See <http://gcc.gnu.org/bugs.html> for instructions.
> > make[4]: *** [_lshrdi3.o] Error 1
> > 
> > Use "./cc1 -fpreprocessed this.i -O2" to repeat.
> > 
> > struct DWstruct {int low, high;};
> > 
> > typedef union
> > {
> >   struct DWstruct s;
> >   long long ll;
> > } DWunion;
> > 
> > long long
> > __lshrdi3 (long long u, int b)
> > {
> >   if (b == 0)
> >     return u;
> > 
> >   const DWunion uu = {.ll = u};
> >   const int bm = (4 * (8)) - b;
> >   DWunion w;
> > 
> >   if (bm <= 0)
> >     {
> >       w.s.high = 0;
> >       w.s.low = (unsigned int) uu.s.high >> -bm;
> >     }
> >   else
> >     {
> >       const unsigned int carries = (unsigned int) uu.s.high << bm;
> > 
> >       w.s.high = (unsigned int) uu.s.high >> b;
> >       w.s.low = ((unsigned int) uu.s.low >> b) | carries;
> >     }
> > 
> >   return w.ll;
> > }
> 
> Sorry about this.
> 
> Looks like I introduced this bug in r214693 (aka patch #225).
> 
> The issue is within resource.c:
> 499			{
> 500			  next = JUMP_LABEL_AS_INSN (this_jump_insn);
> 501			  if (ANY_RETURN_P (next))
> 502			    next = NULL;
> 
> where "next" is an rtx_insn *, but the JUMP_LABEL of this_jump_insn is a
> RETURN, rather than an insn (several such issues in that commit).
> 
> Patch attached, which fixes the above testcase; bootstrap in progress:
> 
> gcc/
> 	* resource.h (mark_target_live_regs): Undo erroneous conversion
> 	of second param of r214693, converting it back from rtx_insn * to
> 	rtx, since it could be a RETURN.
> 
> 	* resource.c (find_dead_or_set_registers): Similarly, convert
> 	param "jump_target" back from an rtx_insn ** to an rtx *, as we
> 	could be writing back a RETURN.  Rename local rtx_insn * "next" to
> 	"next_insn", and introduce "lab_or_return" as a local rtx,
> 	handling the case where JUMP_LABEL (this_jump_insn) is a RETURN.
> 	(mark_target_live_regs): Undo erroneous conversion
> 	of second param of r214693, converting it back from rtx_insn * to
> 	rtx, since it could be a RETURN.  Rename it from "target" to
> 	"target_maybe_return", reintroducing the name "target" as a local
> 	rtx_insn * with a checked cast, after we've handled the case of
> 	ANY_RETURN_P.

...and this has now been filed as part of PR62304, which found both this
and another problem in reorg.c, both with JUMP_LABEL_AS_INSN as the root
cause.  It may be worth eliminating that; it seems error-prone.
diff mbox

Patch

Index: gcc/resource.c
===================================================================
--- gcc/resource.c	(revision 214719)
+++ gcc/resource.c	(working copy)
@@ -81,7 +81,7 @@ 
 static int find_basic_block (rtx, int);
 static rtx_insn *next_insn_no_annul (rtx_insn *);
 static rtx_insn *find_dead_or_set_registers (rtx_insn *, struct resources*,
-					     rtx_insn **, int, struct resources,
+					     rtx *, int, struct resources,
 					     struct resources);
 
 /* Utility function called from mark_target_live_regs via note_stores.
@@ -422,19 +422,20 @@ 
 
 static rtx_insn *
 find_dead_or_set_registers (rtx_insn *target, struct resources *res,
-			    rtx_insn **jump_target, int jump_count,
+			    rtx *jump_target, int jump_count,
 			    struct resources set, struct resources needed)
 {
   HARD_REG_SET scratch;
-  rtx_insn *insn, *next;
+  rtx_insn *insn;
+  rtx_insn *next_insn;
   rtx_insn *jump_insn = 0;
   int i;
 
-  for (insn = target; insn; insn = next)
+  for (insn = target; insn; insn = next_insn)
     {
       rtx_insn *this_jump_insn = insn;
 
-      next = NEXT_INSN (insn);
+      next_insn = NEXT_INSN (insn);
 
       /* If this instruction can throw an exception, then we don't
 	 know where we might end up next.  That means that we have to
@@ -497,14 +498,16 @@ 
 	      if (any_uncondjump_p (this_jump_insn)
 		  || ANY_RETURN_P (PATTERN (this_jump_insn)))
 		{
-		  next = JUMP_LABEL_AS_INSN (this_jump_insn);
-		  if (ANY_RETURN_P (next))
-		    next = NULL;
+		  rtx lab_or_return = JUMP_LABEL (this_jump_insn);
+		  if (ANY_RETURN_P (lab_or_return))
+		    next_insn = NULL;
+		  else
+		    next_insn = as_a <rtx_insn *> (lab_or_return);
 		  if (jump_insn == 0)
 		    {
 		      jump_insn = insn;
 		      if (jump_target)
-			*jump_target = JUMP_LABEL_AS_INSN (this_jump_insn);
+			*jump_target = JUMP_LABEL (this_jump_insn);
 		    }
 		}
 	      else if (any_condjump_p (this_jump_insn))
@@ -572,7 +575,7 @@ 
 		    find_dead_or_set_registers (JUMP_LABEL_AS_INSN (this_jump_insn),
 						&target_res, 0, jump_count,
 						target_set, needed);
-		  find_dead_or_set_registers (next,
+		  find_dead_or_set_registers (next_insn,
 					      &fallthrough_res, 0, jump_count,
 					      set, needed);
 		  IOR_HARD_REG_SET (fallthrough_res.regs, target_res.regs);
@@ -880,7 +883,7 @@ 
    init_resource_info () was invoked before we are called.  */
 
 void
-mark_target_live_regs (rtx_insn *insns, rtx_insn *target, struct resources *res)
+mark_target_live_regs (rtx_insn *insns, rtx target_maybe_return, struct resources *res)
 {
   int b = -1;
   unsigned int i;
@@ -887,19 +890,23 @@ 
   struct target_info *tinfo = NULL;
   rtx_insn *insn;
   rtx jump_insn = 0;
-  rtx_insn *jump_target;
+  rtx jump_target;
   HARD_REG_SET scratch;
   struct resources set, needed;
 
   /* Handle end of function.  */
-  if (target == 0 || ANY_RETURN_P (target))
+  if (target_maybe_return == 0 || ANY_RETURN_P (target_maybe_return))
     {
       *res = end_of_function_needs;
       return;
     }
 
+  /* We've handled the case of RETURN/SIMPLE_RETURN; we should now have an
+     instruction.  */
+  rtx_insn *target = as_a <rtx_insn *> (target_maybe_return);
+
   /* Handle return insn.  */
-  else if (return_insn_p (target))
+  if (return_insn_p (target))
     {
       *res = end_of_function_needs;
       mark_referenced_resources (target, res, false);
Index: gcc/resource.h
===================================================================
--- gcc/resource.h	(revision 214719)
+++ gcc/resource.h	(working copy)
@@ -44,7 +44,7 @@ 
   MARK_SRC_DEST_CALL = 1
 };
 
-extern void mark_target_live_regs (rtx_insn *, rtx_insn *, struct resources *);
+extern void mark_target_live_regs (rtx_insn *, rtx, struct resources *);
 extern void mark_set_resources (rtx, struct resources *, int,
 				enum mark_resource_type);
 extern void mark_referenced_resources (rtx, struct resources *, bool);