This is the mail archive of the gcc-bugs@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]

Re: possible bug in global allocation phase


Heiko Panther wrote:
TEST_HARD_REG_BIT(used, 32) returns 0 and thus r32 is believed to be
available. This happens because "used" is  of type HARD_REG_SET.
HARD_REG_SET is a 32 bit integer type, so a test for nonexisting bits
will produce wrong results.

Yes, this looks like a legitimate bug to me. TEST_HARD_REG_BIT provokes undefined/implementation defined behaviour if given an out-of-range register number. We can get different behaviour for different targets here.


I see 3 uses of this idiom in global.c, 5 in reload.c, 5 in reload1.c, and one in local.c. And that is just a quick check, I haven't tried using grep yet, or trying to verify the count.

I think we need to fix all such occurences by adding a check against FIRST_PSEUDO_REGISTER.

I have attached an incomplete example patch showing what I propose.
--
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com
Index: global.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/global.c,v
retrieving revision 1.94
diff -p -r1.94 global.c
*** global.c	19 Jul 2003 14:47:06 -0000	1.94
--- global.c	22 Oct 2003 19:54:03 -0000
*************** find_reg (int num, HARD_REG_SET losers, 
*** 1051,1056 ****
--- 1051,1057 ----
  	      int lim = regno + HARD_REGNO_NREGS (regno, mode);
  	      for (j = regno + 1;
  		   (j < lim
+ 		    && j < FIRST_PSEUDO_REGISTER
  		    && ! TEST_HARD_REG_BIT (used, j));
  		   j++);
  	      if (j == lim)
*************** find_reg (int num, HARD_REG_SET losers, 
*** 1098,1103 ****
--- 1099,1105 ----
  	      int lim = i + HARD_REGNO_NREGS (i, mode);
  	      for (j = i + 1;
  		   (j < lim
+ 		    && j < FIRST_PSEUDO_REGISTER
  		    && ! TEST_HARD_REG_BIT (used, j)
  		    && (REGNO_REG_CLASS (j)
  			== REGNO_REG_CLASS (best_reg + (j - i))
*************** find_reg (int num, HARD_REG_SET losers, 
*** 1137,1142 ****
--- 1139,1145 ----
  	      int lim = i + HARD_REGNO_NREGS (i, mode);
  	      for (j = i + 1;
  		   (j < lim
+ 		    && j < FIRST_PSEUDO_REGISTER
  		    && ! TEST_HARD_REG_BIT (used, j)
  		    && (REGNO_REG_CLASS (j)
  			== REGNO_REG_CLASS (best_reg + (j - i))

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