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)