Legitimacy of replacing divide-by-power-of-2 with right shifts.
Kimmo Fredriksson
kfredrik@cs.joensuu.fi
Thu Apr 20 17:27:00 GMT 2006
On Thu, 20 Apr 2006, Dave Korn wrote:
>
> Hello, gcc-hackers!
>
> This is somewhat chopped-down from the original code it began life as, but
> it serves to illustrate the point.
>
> unsigned int PhyFrameConfig (unsigned int channelPrf, unsigned int bpp,
> unsigned int bufferSize)
> {
> unsigned int prfShift;
> unsigned int symbolOffset;
> unsigned int symbolShift;
> unsigned int config;
>
> switch (channelPrf)
> {
> case (0):
> prfShift = 0;
> symbolOffset = ((32) * 1) / (1 << bpp);
> break;
Why not:
symbolOffset = ((32) * 1) >> bpp;
?
K
>
> case (1):
> prfShift = 1;
> symbolOffset = ((32) * 2) / (1 << bpp);
> break;
>
> case (3):
> prfShift = 2;
> symbolOffset = ((32) * 4) / (1 << bpp);
> break;
>
> default:
> prfShift = 0;
> symbolOffset = 0;
> ;
> break;
> }
> return symbolOffset;
> }
>
>
> When I compile this (on a custom target, but the result is reproducible on
> x86) the divisions are implemented with calls to __divsi3 (or with idivl insns
> on x86).
>
> Yet it would seem to me at first glance that, since dividing unsigned by an
> exact power-of-2 can be optimised to a right shift, and since we can deduce
> that (1 << bpp) is always going to be a power-of-2, and since absolutely
> everything is unsigned in this case, we ought to have used right-shifts by
> (bpp) bits instead. (Actually, to be completely accurate, in my original case
> I have (2 << bpp) and want to right-shift by (bpp+1) bits, but I'll start with
> the simpler case first).
>
> Is there some corner case / overflow / other catch that I just can't see
> that makes this an invalid case? Is it just the worry about silly values of
> bpp that prevents this optimisation being allowed? It would be fine if bpp
> was a known constant; why is it not fine if bpp is an unknown constant?
>
> cheers,
> DaveK
> --
> Can't think of a witty .sigline today....
>
More information about the Gcc
mailing list