[fpc-devel] bitwise shift oddity a << b

Jonas Maebe jonas.maebe at elis.ugent.be
Tue May 19 14:56:12 CEST 2015


Martin Frb wrote on Tue, 19 May 2015:

> "can differ depending on the cpu" IMHO applies to the underlying asm  
> code/instruction.
>
> But I would expect that the compiler should know how this  
> instruction behaves? And then can generate correct code.

Then you first have to define "correct", and then probably use a whole  
bunch of instructions instead of a single one on architectures whose  
shift instructions do not behave according to this definition "correct".

> (Note, I am not asking for negative to work, never expected that. I  
> am puzzled about the diff between constant eval, and run time eval.

Constant integer expressions are typeless (other than that they are  
whole numbers) and are correct to the limit of the compiler's  
supported range (which is low(int64) to high(qword) at this time). Run  
time expressions are executed using a fixed type  
(http://bugs.freepascal.org/view.php?id=27739#c82395 ) rather than  
always evaluated using this "65 bit" arithmetic.

> In any case the compiler can cast the argument to a unsigned type  
> (making it a very big number)
>    a << cardinal(b)
>
> Then there is also the maximum size of this argument (on a 64 bit  
> cpu,  any number greater 63 will empty the 1st operand).

No, it doesn't. Not on all architectures, at least. And on some  
architectures (certain) shift values > 63 will set the value to 0,  
while others don't.

> So unless there is a cpu that does not allow 64 as argument,

On x86-64, x shr 64 = x, for any value of x. On i386, x shr 32 = x,  
for any value of x. For PowerPC (32 bit), x shr y = 0 if bit 5 of y is  
set, otherwise it's (x shr (y mod 32)). Really, there are very good  
reasons to treat this kind of stuff as undefined (unless you want to  
build a language for which the speed of compiled code is irrelevant).  
That's also why range/overflow checking exists as an option: to enable  
you to still catch such cases if you want, but to not burden all code  
all the time with these checks.


Jonas



More information about the fpc-devel mailing list