expmed.c (synth_mult): When trying out a shift, pass the result of a signed shift.

* expmed.c (synth_mult): When trying out a shift, pass the result
	of a signed shift.

From-SVN: r147087
This commit is contained in:
Kazu Hirata 2009-05-03 23:31:18 +00:00 committed by Kazu Hirata
parent ef268d34b7
commit ddc2690ac0
2 changed files with 37 additions and 0 deletions

View File

@ -1,3 +1,8 @@
2009-05-04 Kazu Hirata <kazu@codesourcery.com>
* expmed.c (synth_mult): When trying out a shift, pass the result
of a signed shift.
2009-05-04 Kazu Hirata <kazu@codesourcery.com>
* expmed.c (shiftsub_cost): Rename to shiftsub0_cost.

View File

@ -2551,6 +2551,38 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
best_alg->log[best_alg->ops] = m;
best_alg->op[best_alg->ops] = alg_shift;
}
/* See if treating ORIG_T as a signed number yields a better
sequence. Try this sequence only for a negative ORIG_T
as it would be useless for a non-negative ORIG_T. */
if ((HOST_WIDE_INT) orig_t < 0)
{
/* Shift ORIG_T as follows because a right shift of a
negative-valued signed type is implementation
defined. */
q = ~(~orig_t >> m);
/* The function expand_shift will choose between a shift
and a sequence of additions, so the observed cost is
given as MIN (m * add_cost[speed][mode],
shift_cost[speed][mode][m]). */
op_cost = m * add_cost[speed][mode];
if (shift_cost[speed][mode][m] < op_cost)
op_cost = shift_cost[speed][mode][m];
new_limit.cost = best_cost.cost - op_cost;
new_limit.latency = best_cost.latency - op_cost;
synth_mult (alg_in, q, &new_limit, mode);
alg_in->cost.cost += op_cost;
alg_in->cost.latency += op_cost;
if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
{
struct algorithm *x;
best_cost = alg_in->cost;
x = alg_in, alg_in = best_alg, best_alg = x;
best_alg->log[best_alg->ops] = m;
best_alg->op[best_alg->ops] = alg_shift;
}
}
}
if (cache_hit)
goto done;