* 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:
Yuriy Sydorov 2021-10-04 17:55:14 +03:00
parent 3989a01968
commit e9d318e7e2
2 changed files with 59 additions and 11 deletions

View File

@ -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
View 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.