expmed.c (synth_mult, [...]): Guard uses of shift_cost, shiftadd_cost and shiftsub_cost with bound checks.

* expmed.c (synth_mult, expand_mult_highpart, expand_divmod): Guard
	uses of shift_cost, shiftadd_cost and shiftsub_cost with bound checks.

From-SVN: r39165
This commit is contained in:
J"orn Rennecke 2001-01-21 09:19:15 +00:00 committed by Joern Rennecke
parent 625b1acd10
commit 02a65aef50
2 changed files with 64 additions and 32 deletions

View File

@ -1,3 +1,8 @@
Sun Jan 21 02:38:56 2001 J"orn Rennecke <amylaar@redhat.com>
* expmed.c (synth_mult, expand_mult_highpart, expand_divmod): Guard
uses of shift_cost, shiftadd_cost and shiftsub_cost with bound checks.
Sun Jan 21 09:44:17 2001 Denis Chertykov <denisc@overta.ru>
* config/avr/avr.c (ret_cond_branch): New argument (reverse) added.

View File

@ -2137,6 +2137,8 @@ synth_mult (alg_out, t, cost_limit)
if ((t & 1) == 0)
{
m = floor_log2 (t & -t); /* m = number of low zero bits */
if (m < BITS_PER_WORD)
{
q = t >> m;
cost = shift_cost[m];
synth_mult (alg_in, q, cost_limit - cost);
@ -2151,6 +2153,7 @@ synth_mult (alg_out, t, cost_limit)
cost_limit = cost;
}
}
}
/* If we have an odd number, add or subtract one. */
if ((t & 1) != 0)
@ -2219,7 +2222,7 @@ synth_mult (alg_out, t, cost_limit)
unsigned HOST_WIDE_INT d;
d = ((unsigned HOST_WIDE_INT) 1 << m) + 1;
if (t % d == 0 && t > d)
if (t % d == 0 && t > d && m < BITS_PER_WORD)
{
cost = MIN (shiftadd_cost[m], add_cost + shift_cost[m]);
synth_mult (alg_in, t / d, cost_limit - cost);
@ -2238,7 +2241,7 @@ synth_mult (alg_out, t, cost_limit)
}
d = ((unsigned HOST_WIDE_INT) 1 << m) - 1;
if (t % d == 0 && t > d)
if (t % d == 0 && t > d && m < BITS_PER_WORD)
{
cost = MIN (shiftsub_cost[m], add_cost + shift_cost[m]);
synth_mult (alg_in, t / d, cost_limit - cost);
@ -2263,7 +2266,7 @@ synth_mult (alg_out, t, cost_limit)
q = t - 1;
q = q & -q;
m = exact_log2 (q);
if (m >= 0)
if (m >= 0 && m < BITS_PER_WORD)
{
cost = shiftadd_cost[m];
synth_mult (alg_in, (t - 1) >> m, cost_limit - cost);
@ -2282,7 +2285,7 @@ synth_mult (alg_out, t, cost_limit)
q = t + 1;
q = q & -q;
m = exact_log2 (q);
if (m >= 0)
if (m >= 0 && m < BITS_PER_WORD)
{
cost = shiftsub_cost[m];
synth_mult (alg_in, (t + 1) >> m, cost_limit - cost);
@ -2815,7 +2818,9 @@ expand_mult_highpart (mode, op0, cnst1, target, unsignedp, max_cost)
/* Secondly, same as above, but use sign flavor opposite of unsignedp.
Need to adjust the result after the multiplication. */
if (mul_highpart_cost[(int) mode] + 2 * shift_cost[size-1] + 4 * add_cost < max_cost)
if (size - 1 < BITS_PER_WORD
&& (mul_highpart_cost[(int) mode] + 2 * shift_cost[size-1] + 4 * add_cost
< max_cost))
{
mul_highpart_optab = unsignedp ? smul_highpart_optab : umul_highpart_optab;
target = expand_binop (mode, mul_highpart_optab,
@ -2838,6 +2843,7 @@ expand_mult_highpart (mode, op0, cnst1, target, unsignedp, max_cost)
/* Try widening the mode and perform a non-widening multiplication. */
moptab = smul_optab;
if (smul_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
&& size - 1 < BITS_PER_WORD
&& mul_cost[(int) wider_mode] + shift_cost[size-1] < max_cost)
{
op1 = wide_op1;
@ -2847,6 +2853,7 @@ expand_mult_highpart (mode, op0, cnst1, target, unsignedp, max_cost)
/* Try widening multiplication of opposite signedness, and adjust. */
moptab = unsignedp ? smul_widen_optab : umul_widen_optab;
if (moptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
&& size - 1 < BITS_PER_WORD
&& (mul_widen_cost[(int) wider_mode]
+ 2 * shift_cost[size-1] + 4 * add_cost < max_cost))
{
@ -3183,6 +3190,9 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
{
rtx t1, t2, t3, t4;
if (post_shift - 1 >= BITS_PER_WORD)
goto fail1;
extra_cost = (shift_cost[post_shift - 1]
+ shift_cost[1] + 2 * add_cost);
t1 = expand_mult_highpart (compute_mode, op0, ml,
@ -3207,6 +3217,10 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
{
rtx t1, t2;
if (pre_shift >= BITS_PER_WORD
|| post_shift >= BITS_PER_WORD)
goto fail1;
t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
build_int_2 (pre_shift, 0),
NULL_RTX, 1);
@ -3327,6 +3341,10 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
{
rtx t1, t2, t3;
if (post_shift >= BITS_PER_WORD
|| size - 1 >= BITS_PER_WORD)
goto fail1;
extra_cost = (shift_cost[post_shift]
+ shift_cost[size - 1] + add_cost);
t1 = expand_mult_highpart (compute_mode, op0, ml,
@ -3353,6 +3371,10 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
{
rtx t1, t2, t3, t4;
if (post_shift >= BITS_PER_WORD
|| size - 1 >= BITS_PER_WORD)
goto fail1;
ml |= (~(unsigned HOST_WIDE_INT) 0) << (size - 1);
extra_cost = (shift_cost[post_shift]
+ shift_cost[size - 1] + 2 * add_cost);
@ -3436,8 +3458,12 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
if (mh)
abort ();
if (post_shift < BITS_PER_WORD
&& size - 1 < BITS_PER_WORD)
{
t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
build_int_2 (size - 1, 0), NULL_RTX, 0);
build_int_2 (size - 1, 0),
NULL_RTX, 0);
t2 = expand_binop (compute_mode, xor_optab, op0, t1,
NULL_RTX, 0, OPTAB_WIDEN);
extra_cost = (shift_cost[post_shift]
@ -3456,6 +3482,7 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
}
}
}
}
else
{
rtx nsign, t1, t2, t3, t4;