J. Gareth Moreton

2018-06-12 00:07:37 UTC

https://bugs.freepascal.org/view.php?id=33851

Someone pointed out that if you perform "(x shl 8) shr 8", where x is of

type Word, the result is always x, even though logic dictates that the

upper 8 bits should be shifted out and hence the result actually be equal

to "x and $FF".Â After analysing the assembly language that's produced, it

turns out that the optimiser works with the full 32-bits of the register.Â

For example:

is_this_a_bug:=((counter shl 8) shr 8);

...becomes the following under -O3 (under -O1, %r13w and %si are replaced

with references)...

movzwl %r13w,%eax

shlÂ Â Â $0x8,%eax

shrÂ Â Â $0x8,%eax

mox Â Â %al,%si

A similar situation happens if the variables are of type Byte as well -

the intermediate values use the full 32 bits of the register.

I'm not certain if this is a bug or intended behaviour though.Â Can

someone more senior make a decision on this?

Gareth

Someone pointed out that if you perform "(x shl 8) shr 8", where x is of

type Word, the result is always x, even though logic dictates that the

upper 8 bits should be shifted out and hence the result actually be equal

to "x and $FF".Â After analysing the assembly language that's produced, it

turns out that the optimiser works with the full 32-bits of the register.Â

For example:

is_this_a_bug:=((counter shl 8) shr 8);

...becomes the following under -O3 (under -O1, %r13w and %si are replaced

with references)...

movzwl %r13w,%eax

shlÂ Â Â $0x8,%eax

shrÂ Â Â $0x8,%eax

mox Â Â %al,%si

A similar situation happens if the variables are of type Byte as well -

the intermediate values use the full 32 bits of the register.

I'm not certain if this is a bug or intended behaviour though.Â Can

someone more senior make a decision on this?

Gareth