[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