From 71dc62dde61909bd587485a20f3c234c832b9389 Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 18 Apr 2021 19:19:35 +0000 Subject: [PATCH] * if left is a smaller type, then an extension operation for shr can be removed git-svn-id: trunk@49231 - --- compiler/ncnv.pas | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/compiler/ncnv.pas b/compiler/ncnv.pas index 4182b2d3ad..f115685a3d 100644 --- a/compiler/ncnv.pas +++ b/compiler/ncnv.pas @@ -2948,6 +2948,11 @@ implementation gotsint:=true; result:=docheckremoveinttypeconvs(tunarynode(n).left); end; + shrn: + begin + result:=wasoriginallysmallerint(tbinarynode(n).left) and + docheckremoveinttypeconvs(tbinarynode(n).right); + end; notn: result:=docheckremoveinttypeconvs(tunarynode(n).left); addn,muln,divn,modn,andn,shln: @@ -2981,15 +2986,26 @@ implementation { remove int type conversions and set the result to the given type } - procedure doremoveinttypeconvs(var n: tnode; todef: tdef; forceunsigned: boolean; signedtype,unsignedtype : tdef); + procedure doremoveinttypeconvs(level : dword;var n: tnode; todef: tdef; forceunsigned: boolean; signedtype,unsignedtype : tdef); var newblock: tblocknode; newstatements: tstatementnode; originaldivtree: tnode; tempnode: ttempcreatenode; begin + { we may not recurse into shr nodes: + + dword1:=dword1+((dword2+dword3) shr 2); + + while we can remove an extension on the addition, we cannot remove it from the shr + } + if (n.nodetype=shrn) and (level<>0) then + begin + inserttypeconv_internal(n,todef); + exit; + end; case n.nodetype of - subn,addn,muln,divn,modn,xorn,andn,orn,shln: + subn,addn,muln,divn,modn,xorn,andn,orn,shln,shrn: begin exclude(n.flags,nf_internal); if not forceunsigned and @@ -2998,8 +3014,8 @@ implementation originaldivtree:=nil; if n.nodetype in [divn,modn] then originaldivtree:=n.getcopy; - doremoveinttypeconvs(tbinarynode(n).left,signedtype,false,signedtype,unsignedtype); - doremoveinttypeconvs(tbinarynode(n).right,signedtype,false,signedtype,unsignedtype); + doremoveinttypeconvs(level+1,tbinarynode(n).left,signedtype,false,signedtype,unsignedtype); + doremoveinttypeconvs(level+1,tbinarynode(n).right,signedtype,false,signedtype,unsignedtype); n.resultdef:=signedtype; if n.nodetype in [divn,modn] then begin @@ -3026,8 +3042,8 @@ implementation end else begin - doremoveinttypeconvs(tbinarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype); - doremoveinttypeconvs(tbinarynode(n).right,unsignedtype,forceunsigned,signedtype,unsignedtype); + doremoveinttypeconvs(level+1,tbinarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype); + doremoveinttypeconvs(level+1,tbinarynode(n).right,unsignedtype,forceunsigned,signedtype,unsignedtype); n.resultdef:=unsignedtype; end; //if ((n.nodetype=andn) and (tbinarynode(n).left.nodetype=ordconstn) and @@ -3044,12 +3060,12 @@ implementation if not forceunsigned and is_signed(n.resultdef) then begin - doremoveinttypeconvs(tunarynode(n).left,signedtype,false,signedtype,unsignedtype); + doremoveinttypeconvs(level+1,tunarynode(n).left,signedtype,false,signedtype,unsignedtype); n.resultdef:=signedtype; end else begin - doremoveinttypeconvs(tunarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype); + doremoveinttypeconvs(level+1,tunarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype); n.resultdef:=unsignedtype; end; end; @@ -3344,22 +3360,22 @@ implementation to 64 bit } if (resultdef.size <= 4) and is_64bitint(left.resultdef) and - (left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln]) and + (left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln,shrn]) and checkremovebiginttypeconvs(left,foundsint,[s8bit,u8bit,s16bit,u16bit,s32bit,u32bit],int64(low(longint)),high(cardinal)) then - doremoveinttypeconvs(left,generrordef,not foundsint,s32inttype,u32inttype); + doremoveinttypeconvs(0,left,generrordef,not foundsint,s32inttype,u32inttype); {$if defined(cpu16bitalu)} if (resultdef.size <= 2) and (is_32bitint(left.resultdef) or is_64bitint(left.resultdef)) and - (left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln]) and + (left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln,shrn]) and checkremovebiginttypeconvs(left,foundsint,[s8bit,u8bit,s16bit,u16bit],int64(low(smallint)),high(word)) then - doremoveinttypeconvs(left,generrordef,not foundsint,s16inttype,u16inttype); + doremoveinttypeconvs(0,left,generrordef,not foundsint,s16inttype,u16inttype); {$endif defined(cpu16bitalu)} {$if defined(cpu8bitalu)} if (resultdef.size