mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-01 23:10:24 +02:00
* x86: Fixed movzwl/movzbl bug in OptPass2Movx (resolves i40003)
This commit is contained in:
parent
348fbfde9d
commit
cc27576339
@ -9652,20 +9652,26 @@ unit aoptx86;
|
||||
{ Convert the output MOVZX to a MOV }
|
||||
if SuperRegistersEqual(taicpu(hp1).oper[1]^.reg, ThisReg) then
|
||||
begin
|
||||
{ Or remove it completely! }
|
||||
DebugMsg(SPeepholeOptimization + 'Movzx2Nop 2', hp1);
|
||||
|
||||
{ Be careful; if p = hp1 and p was also removed, p
|
||||
will become a dangling pointer }
|
||||
if p = hp1 then
|
||||
{ Make sure the zero-expansion covers at least the minimum size (fixes i40003) }
|
||||
if (MinSize = S_B) or
|
||||
(not ShiftDownOverflow and (TryShiftDown = S_B)) or
|
||||
((MinSize = S_W) and (taicpu(hp1).opsize = S_WL)) then
|
||||
begin
|
||||
RemoveCurrentp(p); { p = hp1 and will then become the next instruction }
|
||||
p_removed := True;
|
||||
end
|
||||
else
|
||||
RemoveInstruction(hp1);
|
||||
{ Remove it completely! }
|
||||
DebugMsg(SPeepholeOptimization + 'Movzx2Nop 2', hp1);
|
||||
|
||||
hp1_removed := True;
|
||||
{ Be careful; if p = hp1 and p was also removed, p
|
||||
will become a dangling pointer }
|
||||
if p = hp1 then
|
||||
begin
|
||||
RemoveCurrentp(p); { p = hp1 and will then become the next instruction }
|
||||
p_removed := True;
|
||||
end
|
||||
else
|
||||
RemoveInstruction(hp1);
|
||||
|
||||
hp1_removed := True;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -10583,21 +10589,49 @@ unit aoptx86;
|
||||
if UpperUnsignedOverflow or (taicpu(hp1).oper[0]^.typ <> top_reg) then
|
||||
Break;
|
||||
|
||||
if not SuperRegistersEqual(taicpu(hp1).oper[0]^.reg, ThisReg) then
|
||||
if (InstrMax = -1) then
|
||||
begin
|
||||
if (InstrMax = -1) and
|
||||
{ Will return false if the second parameter isn't ThisReg
|
||||
(can happen on -O2 and under) }
|
||||
Reg1WriteOverwritesReg2Entirely(taicpu(hp1).oper[1]^.reg, ThisReg) then
|
||||
if SuperRegistersEqual(taicpu(hp1).oper[0]^.reg, ThisReg) then
|
||||
begin
|
||||
{ The two MOVZX instructions are adjacent, so remove the first one }
|
||||
DebugMsg(SPeepholeOptimization + 'Movzx2Nop 5', p);
|
||||
RemoveCurrentP(p);
|
||||
Result := True;
|
||||
Exit;
|
||||
end;
|
||||
{ Optimise around i40003 }
|
||||
if SuperRegistersEqual(taicpu(hp1).oper[1]^.reg, ThisReg) and
|
||||
(taicpu(p).opsize = S_WL) and (taicpu(hp1).opsize = S_BL)
|
||||
{$ifndef x86_64}
|
||||
and (
|
||||
(taicpu(p).oper[0]^.typ <> top_reg) or
|
||||
{ Cannot encode byte-sized ESI, EDI, EBP or ESP under i386 }
|
||||
(GetSupReg(taicpu(p).oper[0]^.reg) in [RS_EAX, RS_EBX, RS_ECX, RS_EDX])
|
||||
)
|
||||
{$endif not x86_64}
|
||||
then
|
||||
begin
|
||||
if (taicpu(p).oper[0]^.typ = top_reg) then
|
||||
setsubreg(taicpu(p).oper[0]^.reg, R_SUBL);
|
||||
|
||||
Break;
|
||||
DebugMsg(SPeepholeOptimization + 'movzwl2movzbl 1', p);
|
||||
taicpu(p).opsize := S_BL;
|
||||
|
||||
DebugMsg(SPeepholeOptimization + 'Movzx2Nop 2a', hp1);
|
||||
RemoveInstruction(hp1);
|
||||
Result := True;
|
||||
Exit;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ Will return false if the second parameter isn't ThisReg
|
||||
(can happen on -O2 and under) }
|
||||
if Reg1WriteOverwritesReg2Entirely(taicpu(hp1).oper[1]^.reg, ThisReg) then
|
||||
begin
|
||||
{ The two MOVZX instructions are adjacent, so remove the first one }
|
||||
DebugMsg(SPeepholeOptimization + 'Movzx2Nop 5', p);
|
||||
RemoveCurrentP(p);
|
||||
Result := True;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
|
||||
Result := CompressInstructions;
|
||||
|
Loading…
Reference in New Issue
Block a user