Merge branch 'i41079' into 'main'

[x86_64 / Bug Fix] Fixed problem in "PrePeepholeOptSxx" with 64-bit operands (Fixes #41079)

Closes #41079

See merge request freepascal.org/fpc/source!980
This commit is contained in:
J. Gareth "Kit" Moreton 2025-04-05 00:55:03 +00:00
commit 61cd97a0d4
2 changed files with 51 additions and 3 deletions

View File

@ -1753,7 +1753,15 @@ unit aoptx86;
OpsEqual(taicpu(hp1).oper[1]^, taicpu(p).oper[1]^) then
begin
if (taicpu(p).oper[0]^.val > taicpu(hp1).oper[0]^.val) and
not(cs_opt_size in current_settings.optimizerswitches) then
not(cs_opt_size in current_settings.optimizerswitches)
{$ifdef x86_64}
and (
(taicpu(p).opsize <> S_Q) or
{ 64-bit AND can only store signed 32-bit immediates }
(taicpu(p).oper[0]^.val < 32)
)
{$endif x86_64}
then
begin
{ shr/sar const1, %reg
shl const2, %reg
@ -1772,7 +1780,15 @@ unit aoptx86;
end;
end
else if (taicpu(p).oper[0]^.val<taicpu(hp1).oper[0]^.val) and
not(cs_opt_size in current_settings.optimizerswitches) then
not(cs_opt_size in current_settings.optimizerswitches)
{$ifdef x86_64}
and (
(taicpu(p).opsize <> S_Q) or
{ 64-bit AND can only store signed 32-bit immediates }
(taicpu(p).oper[0]^.val < 32)
)
{$endif x86_64}
then
begin
{ shr/sar const1, %reg
shl const2, %reg
@ -1790,7 +1806,15 @@ unit aoptx86;
Internalerror(2017050702)
end;
end
else if (taicpu(p).oper[0]^.val = taicpu(hp1).oper[0]^.val) then
else if (taicpu(p).oper[0]^.val = taicpu(hp1).oper[0]^.val)
{$ifdef x86_64}
and (
(taicpu(p).opsize <> S_Q) or
{ 64-bit AND can only store signed 32-bit immediates }
(taicpu(p).oper[0]^.val < 32)
)
{$endif x86_64}
then
begin
{ shr/sar const1, %reg
shl const2, %reg

24
tests/webtbs/tw41079.pp Normal file
View File

@ -0,0 +1,24 @@
{ %OPT=-O2 }
program tw41079;
var
A, B, C: QWord;
Fail: Boolean;
begin
A := 140737488355327;
WriteLn('A : ',BinStr(A, 64));
B := (A shr 47) shl 48;
WriteLn('(A shr 47) shl 48: ',BinStr(B, 64));
Fail := B <> 0;
C := A shr 47;
WriteLn('C := A shr 47 : ',BinStr(C, 64));
Fail := Fail or (C <> 0);
C := C shl 48;
WriteLn('C := C shl 48 : ',BinStr(C, 64));
Fail := Fail or (C <> 0);
if Fail then
begin
WriteLn('FAILED');
Halt(1);
end;
WriteLn('ok');
end.