[PATCH] Regression caused by reload_cse_simplify_operands bugs

Ulrich Weigand uweigand@de.ibm.com
Thu Nov 10 23:22:00 GMT 2005


Hello,

the comment in front of reload_cse_simplify_operands says:

   For each non-register operand in the insn, see if any hard regs are
   known to be equivalent to that operand.  Record the alternatives which
   can accept these hard registers.  Among all alternatives, select the
   ones which are better or equal to the one currently matching, where
   "better" is in terms of '?' and '!' constraints.  Among the remaining
   alternatives, select the one which replaces most operands with
   hard registers. 

However, the sorting logic inside that routine actually choses the
alternative which replaces the *least* operands with hard registers,
making the whole exercise somewhat pointless ...

While debugging this (which shows as a performance regression when
generating -march=z9-109 code over -march=z990 code), I noticed another
bug: in the loop scanning all alternatives, the variable 'class' holding
the accumulated register class accepted by the current alternative needs
to be reset to NO_REGS before processing the next alternative.

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux.
OK for mainline?

Bye,
Ulrich


ChangeLog:

	* postreload.c (reload_cse_simplify_operands): Fix bug in sorting
	algorithm so as to choose the best, not the worst, alternative.
	Reset accumulated register class before processing next alternative.

Index: gcc/postreload.c
===================================================================
*** gcc/postreload.c	(revision 106590)
--- gcc/postreload.c	(working copy)
*************** reload_cse_simplify_operands (rtx insn, 
*** 575,580 ****
--- 575,581 ----
  		      op_alt_regno[i][j] = regno;
  		    }
  		  j++;
+ 		  class = (int) NO_REGS;
  		  break;
  		}
  	      p += CONSTRAINT_LEN (c, p);
*************** reload_cse_simplify_operands (rtx insn, 
*** 607,613 ****
  	  int this_nregs = alternative_nregs[alternative_order[j]];
  
  	  if (this_reject < best_reject
! 	      || (this_reject == best_reject && this_nregs < best_nregs))
  	    {
  	      best = j;
  	      best_reject = this_reject;
--- 608,614 ----
  	  int this_nregs = alternative_nregs[alternative_order[j]];
  
  	  if (this_reject < best_reject
! 	      || (this_reject == best_reject && this_nregs > best_nregs))
  	    {
  	      best = j;
  	      best_reject = this_reject;
-- 
  Dr. Ulrich Weigand
  Linux on zSeries Development
  Ulrich.Weigand@de.ibm.com



More information about the Gcc-patches mailing list