Bit shift error, depending on optimization level
Consider the following program:
var
A, B, C: QWord;
begin
A := 140737488355327;
WriteLn('A : ',BinStr(A, 64));
B := (A shr 47) shl 48;
WriteLn('(A shr 47) shl 48: ',BinStr(B, 64));
C := A shr 47;
writeln('C := A shr 47 : ',BinStr(C, 64));
C := C shl 48;
WriteLn('C := C shl 48 : ',BinStr(C, 64));
end.
The 2 calculations should give the same result. If you build for Win64 and use -O1 or higher the output will be wrong:
C:\Users\Bart\LazarusProjecten\bugs\Console\bitshift>fpc test.lpr -Px86_64 -O1
Free Pascal Compiler version 3.3.1 [2024/12/18] for x86_64
Copyright (c) 1993-2024 by Florian Klaempfl and others
Target OS: Win64 for x64
Compiling test.lpr
Linking test.exe
17 lines compiled, 0.1 sec, 33872 bytes code, 1732 bytes data
C:\Users\Bart\LazarusProjecten\bugs\Console\bitshift>test
A : 0000000000000000011111111111111111111111111111111111111111111111
(A shr 47) shl 48: 0000000000000000111111111111111111111111111111110000000000000000
C := A shr 47 : 0000000000000000000000000000000000000000000000000000000000000000
C := C shl 48 : 0000000000000000000000000000000000000000000000000000000000000000
You get the correct output with -O-, or compiling for 32-bit (with any value for -O):
C:\Users\Bart\LazarusProjecten\bugs\Console\bitshift>fpc test.lpr -Px86_64
Free Pascal Compiler version 3.3.1 [2024/12/18] for x86_64
Copyright (c) 1993-2024 by Florian Klaempfl and others
Target OS: Win64 for x64
Compiling test.lpr
Linking test.exe
17 lines compiled, 0.1 sec, 33920 bytes code, 1732 bytes data
C:\Users\Bart\LazarusProjecten\bugs\Console\bitshift>test
A : 0000000000000000011111111111111111111111111111111111111111111111
(A shr 47) shl 48: 0000000000000000000000000000000000000000000000000000000000000000
C := A shr 47 : 0000000000000000000000000000000000000000000000000000000000000000
C := C shl 48 : 0000000000000000000000000000000000000000000000000000000000000000
The error does not seem to depend on the state of range-checking or overflow-checking.
Issue originally raised in the forum.
Tested with fpc main (3.3.1-5463-gb28681e91d). (The issue is also present in fpc 3.2.2 and 3.2.0, but not on 3.0.4)