From dbd8259c48e3654620507cfcac4f532ba857aaab Mon Sep 17 00:00:00 2001 From: "J. Gareth \"Curious Kit\" Moreton" Date: Thu, 13 Oct 2022 22:55:14 +0100 Subject: [PATCH] * x86: Fixed mistake in var9 optimisation under -Os; "andl $255,%eax" is not smaller than "movzbl %al,%eax" because the immediate is sign-extended, not zero-extended, so $255 will be stored as a 32-bit value. --- compiler/x86/aoptx86.pas | 68 ++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 38 deletions(-) diff --git a/compiler/x86/aoptx86.pas b/compiler/x86/aoptx86.pas index ac48422acb..888335404b 100644 --- a/compiler/x86/aoptx86.pas +++ b/compiler/x86/aoptx86.pas @@ -12290,44 +12290,36 @@ unit aoptx86; end; {$ifndef i8086} { movzbl %al,%eax cannot be encoded in 16-bit mode (the machine code is equivalent to movzbw %al,%ax } S_BL: - begin - if (getsupreg(taicpu(p).oper[0]^.reg)=getsupreg(taicpu(p).oper[1]^.reg)) and - ( - not IsMOVZXAcceptable - { and $0xff,%eax has a smaller encoding but risks a partial write penalty } - or ( - (cs_opt_size in current_settings.optimizerswitches) and - (taicpu(p).oper[1]^.reg = NR_EAX) - ) - ) then - { Change "movzbl %al, %eax" to "andl $0x0ffh, %eax" } - begin - DebugMsg(SPeepholeOptimization + 'var9',p); - taicpu(p).opcode := A_AND; - taicpu(p).changeopsize(S_L); - taicpu(p).loadConst(0,$ff); - Result := True; - end - else if not IsMOVZXAcceptable and - GetNextInstruction(p, hp1) and - (tai(hp1).typ = ait_instruction) and - (taicpu(hp1).opcode = A_AND) and - MatchOpType(taicpu(hp1),top_const,top_reg) and - (taicpu(hp1).oper[1]^.reg = taicpu(p).oper[1]^.reg) then - { Change "movzbl %reg1, %reg2; andl $const, %reg2" - to "movl %reg1, reg2; andl $(const1 and $ff), %reg2"} - begin - DebugMsg(SPeepholeOptimization + 'var10',p); - taicpu(p).opcode := A_MOV; - taicpu(p).changeopsize(S_L); - { do not use R_SUBWHOLE - as movl %rdx,%eax - is invalid in assembler PM } - setsubreg(taicpu(p).oper[0]^.reg, R_SUBD); - taicpu(hp1).loadConst(0,taicpu(hp1).oper[0]^.val and $ff); - Result := True; - end; - end; + if not IsMOVZXAcceptable then + begin + if (getsupreg(taicpu(p).oper[0]^.reg)=getsupreg(taicpu(p).oper[1]^.reg)) then + { Change "movzbl %al, %eax" to "andl $0x0ffh, %eax" } + begin + DebugMsg(SPeepholeOptimization + 'var9',p); + taicpu(p).opcode := A_AND; + taicpu(p).changeopsize(S_L); + taicpu(p).loadConst(0,$ff); + Result := True; + end + else if GetNextInstruction(p, hp1) and + (tai(hp1).typ = ait_instruction) and + (taicpu(hp1).opcode = A_AND) and + MatchOpType(taicpu(hp1),top_const,top_reg) and + (taicpu(hp1).oper[1]^.reg = taicpu(p).oper[1]^.reg) then + { Change "movzbl %reg1, %reg2; andl $const, %reg2" + to "movl %reg1, reg2; andl $(const1 and $ff), %reg2"} + begin + DebugMsg(SPeepholeOptimization + 'var10',p); + taicpu(p).opcode := A_MOV; + taicpu(p).changeopsize(S_L); + { do not use R_SUBWHOLE + as movl %rdx,%eax + is invalid in assembler PM } + setsubreg(taicpu(p).oper[0]^.reg, R_SUBD); + taicpu(hp1).loadConst(0,taicpu(hp1).oper[0]^.val and $ff); + Result := True; + end; + end; {$endif i8086} S_WL: if not IsMOVZXAcceptable then