mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-08 14:08:09 +02:00
* x86: Fixed update of used registers in the CMOV optimizations.
This fixes a bug reported by Martin Frb in fpc-devel which is triggered by the recently provided test code in FPC 3.2.2 x86_64, but is hidden in trunk by other pipeline peephole optimizations.
This commit is contained in:
parent
3989a01968
commit
e9d318e7e2
@ -8446,6 +8446,7 @@ unit aoptx86;
|
||||
if (l<=4) and (l>0) then
|
||||
begin
|
||||
condition:=inverse_cond(taicpu(p).condition);
|
||||
UpdateUsedRegs(tai(p.next));
|
||||
GetNextInstruction(p,hp1);
|
||||
repeat
|
||||
if not Assigned(hp1) then
|
||||
@ -8453,7 +8454,7 @@ unit aoptx86;
|
||||
|
||||
taicpu(hp1).opcode:=A_CMOVcc;
|
||||
taicpu(hp1).condition:=condition;
|
||||
UpdateUsedRegs(hp1);
|
||||
UpdateUsedRegs(tai(hp1.next));
|
||||
GetNextInstruction(hp1,hp1);
|
||||
until not(CanBeCMOV(hp1));
|
||||
|
||||
@ -8495,6 +8496,7 @@ unit aoptx86;
|
||||
{ Remove the original jump }
|
||||
RemoveInstruction(p); { Note, the choice to not use RemoveCurrentp is deliberate }
|
||||
|
||||
UpdateUsedRegs(tai(hp2.next));
|
||||
GetNextInstruction(hp2, p); { Instruction after the label }
|
||||
|
||||
{ Remove the label if this is its final reference }
|
||||
@ -8502,10 +8504,7 @@ unit aoptx86;
|
||||
StripLabelFast(hp1);
|
||||
|
||||
if Assigned(p) then
|
||||
begin
|
||||
UpdateUsedRegs(p);
|
||||
result:=true;
|
||||
end;
|
||||
result:=true;
|
||||
exit;
|
||||
end;
|
||||
end
|
||||
@ -8555,29 +8554,33 @@ unit aoptx86;
|
||||
FindLabel(tasmlabel(taicpu(hp2).oper[0]^.ref^.symbol),hp1) then
|
||||
begin
|
||||
condition:=inverse_cond(taicpu(p).condition);
|
||||
UpdateUsedRegs(tai(p.next));
|
||||
GetNextInstruction(p,hp1);
|
||||
repeat
|
||||
taicpu(hp1).opcode:=A_CMOVcc;
|
||||
taicpu(hp1).condition:=condition;
|
||||
UpdateUsedRegs(hp1);
|
||||
UpdateUsedRegs(tai(hp1.next));
|
||||
GetNextInstruction(hp1,hp1);
|
||||
until not(assigned(hp1)) or
|
||||
not(CanBeCMOV(hp1));
|
||||
|
||||
condition:=inverse_cond(condition);
|
||||
if GetLastInstruction(hpmov2,hp1) then
|
||||
UpdateUsedRegs(tai(hp1.next));
|
||||
hp1 := hpmov2;
|
||||
{ hp1 is now at <several movs 2> }
|
||||
while Assigned(hp1) and CanBeCMOV(hp1) do
|
||||
begin
|
||||
taicpu(hp1).opcode:=A_CMOVcc;
|
||||
taicpu(hp1).condition:=condition;
|
||||
UpdateUsedRegs(hp1);
|
||||
UpdateUsedRegs(tai(hp1.next));
|
||||
GetNextInstruction(hp1,hp1);
|
||||
end;
|
||||
|
||||
hp1 := p;
|
||||
|
||||
{ Get first instruction after label }
|
||||
UpdateUsedRegs(tai(hp3.next));
|
||||
GetNextInstruction(hp3, p);
|
||||
|
||||
if assigned(p) and (hp3.typ = ait_align) then
|
||||
@ -8612,10 +8615,7 @@ unit aoptx86;
|
||||
StripLabelFast(hp3);
|
||||
|
||||
if Assigned(p) then
|
||||
begin
|
||||
UpdateUsedRegs(p);
|
||||
result:=true;
|
||||
end;
|
||||
result:=true;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
48
tests/tbs/tb0686.pp
Normal file
48
tests/tbs/tb0686.pp
Normal file
@ -0,0 +1,48 @@
|
||||
{$mode objfpc}
|
||||
|
||||
uses math;
|
||||
|
||||
type
|
||||
generic TLazFifoQueue<T> = class
|
||||
private
|
||||
FList: array of T;
|
||||
FQueueSize: integer;
|
||||
protected
|
||||
FTotalItemsPopped: QWord;
|
||||
FTotalItemsPushed: QWord;
|
||||
public
|
||||
procedure Grow(ADelta: integer);
|
||||
end;
|
||||
|
||||
procedure TLazFifoQueue.Grow(ADelta: integer);
|
||||
var
|
||||
NewList: array of integer;
|
||||
c: Integer;
|
||||
i: QWord;
|
||||
begin
|
||||
c:=Max(FQueueSize + ADelta, Integer(FTotalItemsPushed - FTotalItemsPopped));
|
||||
setlength(NewList{%H-}, c);
|
||||
i:=FTotalItemsPopped;
|
||||
while i < FTotalItemsPushed do begin
|
||||
NewList[i mod c] := FList[i mod FQueueSize];
|
||||
inc(i);
|
||||
end;
|
||||
|
||||
FList := NewList;
|
||||
FQueueSize:=c;
|
||||
end;
|
||||
|
||||
type
|
||||
TIntQ = specialize TLazFifoQueue<integer>;
|
||||
|
||||
begin
|
||||
with TIntQ.Create do begin
|
||||
Grow(123);
|
||||
if FQueueSize <> 123 then begin
|
||||
writeln('FAILED');
|
||||
halt(1);
|
||||
end;
|
||||
Free;
|
||||
end;
|
||||
writeln('OK');
|
||||
end.
|
Loading…
Reference in New Issue
Block a user