Patch by Gareth Moreton

* Fix lea optimizations which lead to more failures with -O3 and -O4 options.

 - LeaLea2Lea now checks to see if the index register is in use.
 - For both the base and index registers, RegUsedBetween is changed to
 RegModifiedBetween, since just reading the register is harmless for the
 optimisation (it finds additional optimisations in the RTL as a result).
 - Because I saw the mis-optimisation with MOVZX that occurred (even
 though it was due to the mis-optimisation of LEA instructions), I wrote
 some extra code in OptPass2Movx as a safety measure to ensure this
 doesn't happen (although no additional instances of it happening have
 been noted so far - best be safe than sorry).

git-svn-id: trunk@48802 -
This commit is contained in:
pierre 2021-02-24 12:58:04 +00:00
parent e2386ae876
commit 236bef961c

View File

@ -3370,8 +3370,12 @@ unit aoptx86;
(taicpu(hp1).oper[0]^.ref^.segment = NR_NO) and
(taicpu(hp1).oper[0]^.ref^.symbol = nil) and
(
(taicpu(p).oper[0]^.ref^.base = NR_NO) or { Don't call RegUsedBetween unnecessarily }
not(RegUsedBetween(taicpu(p).oper[0]^.ref^.base,p,hp1))
(taicpu(p).oper[0]^.ref^.base = NR_NO) or { Don't call RegModifiedBetween unnecessarily }
not(RegModifiedBetween(taicpu(p).oper[0]^.ref^.base,p,hp1))
) and (
(taicpu(p).oper[0]^.ref^.index = taicpu(p).oper[0]^.ref^.base) or { Don't call RegModifiedBetween unnecessarily }
(taicpu(p).oper[0]^.ref^.index = NR_NO) or
not(RegModifiedBetween(taicpu(p).oper[0]^.ref^.index,p,hp1))
) then
begin
{ changes
@ -5348,6 +5352,25 @@ unit aoptx86;
if not MatchOpType(taicpu(hp1), top_reg, top_reg) then
Break;
if not SuperRegistersEqual(taicpu(hp1).oper[0]^.reg, ThisReg) then
begin
{ Because hp1 was obtained via GetNextInstructionUsingReg
and ThisReg doesn't appear in the first operand, it
must appear in the second operand and hence gets
overwritten }
if (InstrMax = -1) and
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;
{ The objective here is to try to find a combination that
removes one of the MOV/Z instructions. }
case taicpu(hp1).opsize of
@ -5460,8 +5483,7 @@ unit aoptx86;
((TargetSize = S_W) and (taicpu(hp1).opsize in [S_W, S_BW])) then
begin
{ Convert the output MOVZX to a MOV }
if (taicpu(hp1).oper[0]^.typ = top_reg) and
SuperRegistersEqual(taicpu(hp1).oper[1]^.reg, ThisReg) then
if SuperRegistersEqual(taicpu(hp1).oper[1]^.reg, ThisReg) then
begin
{ Or remove it completely! }
DebugMsg(SPeepholeOptimization + 'Movzx2Nop 2', hp1);