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]
Other format: [Raw text]

[PATCH] Fix several endless loops in cse_insn for certain targettypes combinations


I'm working on my own target which my company is not ready to sumbit back yet.
After merging my back-end into gcc 4.0 tree I had multiple hangs of the compiler during libgcc build.
I found several places in cse.c with similar code which supposed to be iterating class of type modes:



for (wider_mode = GET_MODE_WIDER_MODE (mode); GET_MODE_BITSIZE (wider_mode) <= BITS_PER_WORD && src_related == 0; wider_mode = GET_MODE_WIDER_MODE (wider_mode))

But in a situation when widest mode in a class as wide as BITS_PER_WORD (like in my case registers are 128 bits and largest mode we use is TImode), this loop will never stop. So there should be an extra check that VOIDmode is reached.

I couldn't provide a testcase because it's not a case for any back-end currently in the tree, but I hope that my explanation is clear enough and changes are very staight-forward.

I'm attaching two patch files. One agains the 4.0.0 release sources and another one againts current developmenty branch.

Thanks,
Igor Shevlyakov
Microunity, Inc.
Index: cse.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cse.c,v
retrieving revision 1.354
diff -c -3 -p -r1.354 cse.c
*** cse.c	22 Apr 2005 16:14:52 -0000	1.354
--- cse.c	17 May 2005 03:04:04 -0000
*************** cse_insn (rtx insn, rtx libcall_insn)
*** 5169,5174 ****
--- 5169,5175 ----
  
  	  for (wider_mode = GET_MODE_WIDER_MODE (mode);
  	       GET_MODE_BITSIZE (wider_mode) <= BITS_PER_WORD
+ 	       && wider_mode != VOIDmode
  	       && src_related == 0;
  	       wider_mode = GET_MODE_WIDER_MODE (wider_mode))
  	    {
*************** cse_insn (rtx insn, rtx libcall_insn)
*** 5203,5209 ****
  	  rtx new_and = gen_rtx_AND (VOIDmode, NULL_RTX, XEXP (src, 1));
  
  	  for (tmode = GET_MODE_WIDER_MODE (mode);
! 	       GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
  	       tmode = GET_MODE_WIDER_MODE (tmode))
  	    {
  	      rtx inner = gen_lowpart (tmode, XEXP (src, 0));
--- 5204,5211 ----
  	  rtx new_and = gen_rtx_AND (VOIDmode, NULL_RTX, XEXP (src, 1));
  
  	  for (tmode = GET_MODE_WIDER_MODE (mode);
! 	       GET_MODE_SIZE (tmode) <= UNITS_PER_WORD
! 	       && tmode != VOIDmode;
  	       tmode = GET_MODE_WIDER_MODE (tmode))
  	    {
  	      rtx inner = gen_lowpart (tmode, XEXP (src, 0));
*************** cse_insn (rtx insn, rtx libcall_insn)
*** 5255,5261 ****
  	  XEXP (memory_extend_rtx, 0) = src;
  
  	  for (tmode = GET_MODE_WIDER_MODE (mode);
! 	       GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
  	       tmode = GET_MODE_WIDER_MODE (tmode))
  	    {
  	      struct table_elt *larger_elt;
--- 5257,5264 ----
  	  XEXP (memory_extend_rtx, 0) = src;
  
  	  for (tmode = GET_MODE_WIDER_MODE (mode);
! 	       GET_MODE_SIZE (tmode) <= UNITS_PER_WORD
! 	       && tmode != VOIDmode;
  	       tmode = GET_MODE_WIDER_MODE (tmode))
  	    {
  	      struct table_elt *larger_elt;
2005-05-16  Igor Shevlyakov  <igor@microunity.com>

	* cse.c (cse_insn):  Alternative check for the end of a class
	of modes. Prevents endless loop when largest mode have a size
	of BITS_PER_WORD.
Index: cse.c
===================================================================
RCS file: /p/cvsroot/gnu-new/gcc/cse.c,v
retrieving revision 1.1.1.1
diff -c -3 -p -r1.1.1.1 cse.c
*** cse.c	27 Apr 2005 22:51:48 -0000	1.1.1.1
--- cse.c	10 May 2005 21:17:27 -0000
*************** cse_insn (rtx insn, rtx libcall_insn)
*** 5180,5185 ****
--- 5180,5186 ----
  
  	  for (wider_mode = GET_MODE_WIDER_MODE (mode);
  	       GET_MODE_BITSIZE (wider_mode) <= BITS_PER_WORD
+ 	       && wider_mode != VOIDmode
  	       && src_related == 0;
  	       wider_mode = GET_MODE_WIDER_MODE (wider_mode))
  	    {
*************** cse_insn (rtx insn, rtx libcall_insn)
*** 5214,5220 ****
  	  rtx new_and = gen_rtx_AND (VOIDmode, NULL_RTX, XEXP (src, 1));
  
  	  for (tmode = GET_MODE_WIDER_MODE (mode);
! 	       GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
  	       tmode = GET_MODE_WIDER_MODE (tmode))
  	    {
  	      rtx inner = gen_lowpart (tmode, XEXP (src, 0));
--- 5215,5222 ----
  	  rtx new_and = gen_rtx_AND (VOIDmode, NULL_RTX, XEXP (src, 1));
  
  	  for (tmode = GET_MODE_WIDER_MODE (mode);
! 	       GET_MODE_SIZE (tmode) <= UNITS_PER_WORD
! 	       && tmode != VOIDmode;
  	       tmode = GET_MODE_WIDER_MODE (tmode))
  	    {
  	      rtx inner = gen_lowpart (tmode, XEXP (src, 0));
*************** cse_insn (rtx insn, rtx libcall_insn)
*** 5266,5272 ****
  	  XEXP (memory_extend_rtx, 0) = src;
  
  	  for (tmode = GET_MODE_WIDER_MODE (mode);
! 	       GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
  	       tmode = GET_MODE_WIDER_MODE (tmode))
  	    {
  	      struct table_elt *larger_elt;
--- 5268,5275 ----
  	  XEXP (memory_extend_rtx, 0) = src;
  
  	  for (tmode = GET_MODE_WIDER_MODE (mode);
! 	       GET_MODE_SIZE (tmode) <= UNITS_PER_WORD
! 	       && tmode != VOIDmode;
  	       tmode = GET_MODE_WIDER_MODE (tmode))
  	    {
  	      struct table_elt *larger_elt;

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