From dd7e472fa45cdddfc81a83b923f29fe9ecec8eec Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Thu, 10 Dec 2009 21:08:31 +0000 Subject: [PATCH] * don't convert "cardinal div (cardinal-cardinal)" to longint after it has been upcasted to int64, but convert it back to cardinal (mantis #15015) * put the "remove unnecessary 64 bit type conversions" code between {$ifndef cpu64bitalu} instead of {$ifndef cpu64bitaddr} git-svn-id: trunk@14396 - --- .gitattributes | 1 + compiler/ncnv.pas | 32 ++++++++++++++++++-------------- tests/webtbs/tw15015.pp | 13 +++++++++++++ 3 files changed, 32 insertions(+), 14 deletions(-) create mode 100644 tests/webtbs/tw15015.pp diff --git a/.gitattributes b/.gitattributes index 9b2f4398cc..9f36e896fa 100644 --- a/.gitattributes +++ b/.gitattributes @@ -10107,6 +10107,7 @@ tests/webtbs/tw1489.pp svneol=native#text/plain tests/webtbs/tw14958a.pp svneol=native#text/plain tests/webtbs/tw14958b.pp svneol=native#text/plain tests/webtbs/tw1501.pp svneol=native#text/plain +tests/webtbs/tw15015.pp svneol=native#text/plain tests/webtbs/tw15088.pp svneol=native#text/plain tests/webtbs/tw15169.pp svneol=native#text/plain tests/webtbs/tw15207.pp svneol=native#text/plain diff --git a/compiler/ncnv.pas b/compiler/ncnv.pas index 6968d91c8f..6c0b0f4e30 100644 --- a/compiler/ncnv.pas +++ b/compiler/ncnv.pas @@ -1934,15 +1934,15 @@ implementation end; -{$ifndef cpu64bitaddr} +{$ifndef cpu64bitalu} { checks whether we can safely remove 64 bit typeconversions } { in case range and overflow checking are off, and in case } { the result of this node tree is downcasted again to a } { 8/16/32 bit value afterwards } - function checkremove64bittypeconvs(n: tnode): boolean; + function checkremove64bittypeconvs(n: tnode; out gotsint: boolean): boolean; var - gotmuldivmod, gotsint: boolean; + gotmuldivmod: boolean; { checks whether a node is either an u32bit, or originally } { was one but was implicitly converted to s64bit } @@ -2021,22 +2021,23 @@ implementation end; - procedure doremove64bittypeconvs(var n: tnode; todef: tdef); + procedure doremove64bittypeconvs(var n: tnode; todef: tdef; forceunsigned: boolean); begin case n.nodetype of subn,addn,muln,divn,modn,xorn,andn,orn: begin exclude(n.flags,nf_internal); - if is_signed(n.resultdef) then + if not forceunsigned and + is_signed(n.resultdef) then begin - doremove64bittypeconvs(tbinarynode(n).left,s32inttype); - doremove64bittypeconvs(tbinarynode(n).right,s32inttype); + doremove64bittypeconvs(tbinarynode(n).left,s32inttype,false); + doremove64bittypeconvs(tbinarynode(n).right,s32inttype,false); n.resultdef:=s32inttype end else begin - doremove64bittypeconvs(tbinarynode(n).left,u32inttype); - doremove64bittypeconvs(tbinarynode(n).right,u32inttype); + doremove64bittypeconvs(tbinarynode(n).left,u32inttype,forceunsigned); + doremove64bittypeconvs(tbinarynode(n).right,u32inttype,forceunsigned); n.resultdef:=u32inttype end; end; @@ -2046,12 +2047,15 @@ implementation n.resultdef:=todef; end; end; -{$endif not cpu64bitaddr} +{$endif not cpu64bitalu} function ttypeconvnode.simplify: tnode; var hp: tnode; +{$ifndef cpu64bitalu} + foundsint: boolean; +{$endif not cpu64bitalu} begin result := nil; { Constant folding and other node transitions to @@ -2211,7 +2215,7 @@ implementation end; end; -{$ifndef cpu64bitaddr} +{$ifndef cpu64bitalu} { must be done before code below, because we need the typeconversions for ordconstn's as well } case convtype of @@ -2222,15 +2226,15 @@ implementation (resultdef.size <= 4) and is_64bitint(left.resultdef) and (left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn]) and - checkremove64bittypeconvs(left) then + checkremove64bittypeconvs(left,foundsint) then begin { avoid unnecessary widening of intermediary calculations } { to 64 bit } - doremove64bittypeconvs(left,generrordef); + doremove64bittypeconvs(left,generrordef,not foundsint); end; end; end; -{$endif not cpu64bitaddr} +{$endif not cpu64bitalu} end; diff --git a/tests/webtbs/tw15015.pp b/tests/webtbs/tw15015.pp new file mode 100644 index 0000000000..a2f21ae964 --- /dev/null +++ b/tests/webtbs/tw15015.pp @@ -0,0 +1,13 @@ +program tget2; + +var + a, b: LongWord; + +begin + a := 307; + b := 1 + ($FFFFFFFF mod (a - 2)); + writeln(b); + if b <> 301 then Halt(1); + writeln(1 + $FFFFFFFF mod (a - 2)); + if b <> 301 then Halt(1); +end.