* factored out the conditions under which add nodes need to perform

overflow checks
   o in particular ensure that cpu-specific overrides don't perform overflow
     checks when nf_internal is set

git-svn-id: trunk@42573 -
This commit is contained in:
Jonas Maebe 2019-08-03 12:19:50 +00:00
parent c70f2c63cd
commit ce598c15ec
13 changed files with 54 additions and 39 deletions

1
.gitattributes vendored
View File

@ -12926,6 +12926,7 @@ tests/tbs/tb0654.pp svneol=native#text/plain
tests/tbs/tb0655.pp svneol=native#text/pascal tests/tbs/tb0655.pp svneol=native#text/pascal
tests/tbs/tb0656.pp svneol=native#text/pascal tests/tbs/tb0656.pp svneol=native#text/pascal
tests/tbs/tb0657.pp svneol=native#text/pascal tests/tbs/tb0657.pp svneol=native#text/pascal
tests/tbs/tb0658.pp svneol=native#text/plain
tests/tbs/tb205.pp svneol=native#text/plain tests/tbs/tb205.pp svneol=native#text/plain
tests/tbs/tb610.pp svneol=native#text/pascal tests/tbs/tb610.pp svneol=native#text/pascal
tests/tbs/tb613.pp svneol=native#text/plain tests/tbs/tb613.pp svneol=native#text/plain

View File

@ -728,7 +728,7 @@ interface
begin begin
result:=GenerateThumbCode or result:=GenerateThumbCode or
not(CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype]) or not(CPUARM_HAS_UMULL in cpu_capabilities[current_settings.cputype]) or
(cs_check_overflow in current_settings.localswitches); needoverflowcheck;
end; end;
begin begin

View File

@ -64,7 +64,7 @@ interface
function ti386addnode.use_generic_mul64bit: boolean; function ti386addnode.use_generic_mul64bit: boolean;
begin begin
result:=(cs_check_overflow in current_settings.localswitches) or result:=needoverflowcheck or
(cs_opt_size in current_settings.optimizerswitches); (cs_opt_size in current_settings.optimizerswitches);
end; end;
@ -78,7 +78,7 @@ interface
not(is_signed(right.resultdef)); not(is_signed(right.resultdef));
{ use IMUL instead of MUL in case overflow checking is off and we're { use IMUL instead of MUL in case overflow checking is off and we're
doing a 32->32-bit multiplication } doing a 32->32-bit multiplication }
if not (cs_check_overflow in current_settings.localswitches) and if not needoverflowcheck and
not is_64bit(resultdef) then not is_64bit(resultdef) then
unsigned:=false; unsigned:=false;
if (nodetype=muln) and (unsigned or is_64bit(resultdef)) then if (nodetype=muln) and (unsigned or is_64bit(resultdef)) then
@ -213,7 +213,7 @@ interface
{ is in unsigned VAR!! } { is in unsigned VAR!! }
if mboverflow then if mboverflow then
begin begin
if cs_check_overflow in current_settings.localswitches then if needoverflowcheck then
begin begin
current_asmdata.getjumplabel(hl4); current_asmdata.getjumplabel(hl4);
if unsigned then if unsigned then
@ -487,7 +487,7 @@ interface
emit_ref(asmops[unsigned],S_L,ref) emit_ref(asmops[unsigned],S_L,ref)
else else
emit_reg(asmops[unsigned],S_L,reg); emit_reg(asmops[unsigned],S_L,reg);
if (cs_check_overflow in current_settings.localswitches) and if needoverflowcheck and
{ 32->64 bit cannot overflow } { 32->64 bit cannot overflow }
(not is_64bit(resultdef)) then (not is_64bit(resultdef)) then
begin begin

View File

@ -315,7 +315,7 @@ interface
{ is in unsigned VAR!! } { is in unsigned VAR!! }
if mboverflow then if mboverflow then
begin begin
if cs_check_overflow in current_settings.localswitches then if needoverflowcheck then
begin begin
current_asmdata.getjumplabel(hl4); current_asmdata.getjumplabel(hl4);
if unsigned then if unsigned then
@ -1002,6 +1002,7 @@ interface
ref:Treference; ref:Treference;
use_ref:boolean; use_ref:boolean;
hl4 : tasmlabel; hl4 : tasmlabel;
overflowcheck: boolean;
const const
asmops: array[boolean] of tasmop = (A_IMUL, A_MUL); asmops: array[boolean] of tasmop = (A_IMUL, A_MUL);
@ -1012,10 +1013,12 @@ interface
pass_left_right; pass_left_right;
overflowcheck:=needoverflowcheck;
{ MUL is faster than IMUL on the 8086 & 8088 (and equal in speed on 286+), { MUL is faster than IMUL on the 8086 & 8088 (and equal in speed on 286+),
but it's only safe to use in place of IMUL when overflow checking is off but it's only safe to use in place of IMUL when overflow checking is off
and we're doing a 16-bit>16-bit multiplication } and we're doing a 16-bit>16-bit multiplication }
if not (cs_check_overflow in current_settings.localswitches) and if not overflowcheck and
(not is_32bitint(resultdef)) then (not is_32bitint(resultdef)) then
unsigned:=true; unsigned:=true;
@ -1048,7 +1051,7 @@ interface
emit_ref(asmops[unsigned],S_W,ref) emit_ref(asmops[unsigned],S_W,ref)
else else
emit_reg(asmops[unsigned],S_W,reg); emit_reg(asmops[unsigned],S_W,reg);
if (cs_check_overflow in current_settings.localswitches) and if overflowcheck and
{ 16->32 bit cannot overflow } { 16->32 bit cannot overflow }
(not is_32bitint(resultdef)) then (not is_32bitint(resultdef)) then
begin begin

View File

@ -399,9 +399,7 @@ implementation
begin begin
{ if we need to handle overflow checking, fall back to the generic cg } { if we need to handle overflow checking, fall back to the generic cg }
if (nodetype in [addn,subn,muln]) and if (nodetype in [addn,subn,muln]) and
(left.resultdef.typ<>pointerdef) and needoverflowcheck then
(right.resultdef.typ<>pointerdef) and
(cs_check_overflow in current_settings.localswitches) then
begin begin
inherited; inherited;
exit; exit;
@ -609,7 +607,7 @@ implementation
function t68kaddnode.use_generic_mul64bit: boolean; function t68kaddnode.use_generic_mul64bit: boolean;
begin begin
result:=(cs_check_overflow in current_settings.localswitches) or result:=needoverflowcheck or
(cs_opt_size in current_settings.optimizerswitches) or (cs_opt_size in current_settings.optimizerswitches) or
not (CPUM68K_HAS_64BITMUL in cpu_capabilities[current_settings.cputype]); not (CPUM68K_HAS_64BITMUL in cpu_capabilities[current_settings.cputype]);
end; end;

View File

@ -426,7 +426,7 @@ end;
function tmipsaddnode.use_generic_mul64bit: boolean; function tmipsaddnode.use_generic_mul64bit: boolean;
begin begin
result:=(cs_check_overflow in current_settings.localswitches) or result:=needoverflowcheck or
(not (CPUMIPS_HAS_ISA32R2 in cpu_capabilities[current_settings.cputype])); (not (CPUMIPS_HAS_ISA32R2 in cpu_capabilities[current_settings.cputype]));
end; end;

View File

@ -66,6 +66,8 @@ interface
procedure second_cmpsmallset;virtual;abstract; procedure second_cmpsmallset;virtual;abstract;
procedure second_cmp64bit;virtual;abstract; procedure second_cmp64bit;virtual;abstract;
procedure second_cmpordinal;virtual;abstract; procedure second_cmpordinal;virtual;abstract;
function needoverflowcheck: boolean;
end; end;
implementation implementation
@ -518,9 +520,7 @@ interface
checkoverflow:= checkoverflow:=
checkoverflow and checkoverflow and
(left.resultdef.typ<>pointerdef) and needoverflowcheck;
(right.resultdef.typ<>pointerdef) and
(cs_check_overflow in current_settings.localswitches) and not(nf_internal in flags);
{$if defined(cpu64bitalu) or defined(cpuhighleveltarget)} {$if defined(cpu64bitalu) or defined(cpuhighleveltarget)}
case nodetype of case nodetype of
@ -763,6 +763,15 @@ interface
second_cmpordinal; second_cmpordinal;
end; end;
function tcgaddnode.needoverflowcheck: boolean;
begin
result:=
(cs_check_overflow in current_settings.localswitches) and
(left.resultdef.typ<>pointerdef) and
(right.resultdef.typ<>pointerdef) and
not(nf_internal in flags);
end;
{***************************************************************************** {*****************************************************************************
pass_generate_code; pass_generate_code;

View File

@ -325,11 +325,10 @@ interface
current_asmdata.getjumplabel(falselabel); current_asmdata.getjumplabel(falselabel);
end; end;
load_left_right(cmpop,((cs_check_overflow in current_settings.localswitches) and load_left_right(cmpop,needoverflowcheck or (nodetype = muln));
(nodetype in [addn,subn])) or (nodetype = muln));
if (nodetype <> muln) and if (nodetype<>muln) and
(not(cs_check_overflow in current_settings.localswitches) or (not needoverflowcheck or
not(nodetype in [addn,subn])) then not(nodetype in [addn,subn])) then
begin begin
case nodetype of case nodetype of
@ -657,9 +656,7 @@ interface
checkoverflow:= checkoverflow:=
(nodetype in [addn,subn,muln]) and (nodetype in [addn,subn,muln]) and
(cs_check_overflow in current_settings.localswitches) and needoverflowcheck;
(left.resultdef.typ<>pointerdef) and
(right.resultdef.typ<>pointerdef);
load_left_right(cmpop, checkoverflow); load_left_right(cmpop, checkoverflow);

View File

@ -219,11 +219,7 @@ begin
else else
location_reset(location, LOC_FLAGS, OS_NO); location_reset(location, LOC_FLAGS, OS_NO);
checkoverflow:= checkoverflow:=needoverflowcheck;
(nodetype in [addn,subn,muln]) and
(cs_check_overflow in current_settings.localswitches) and
(left.resultdef.typ<>pointerdef) and
(right.resultdef.typ<>pointerdef);
load_left_right(cmpop, checkoverflow); load_left_right(cmpop, checkoverflow);

View File

@ -505,7 +505,7 @@ interface
function tsparcaddnode.use_generic_mul64bit: boolean; function tsparcaddnode.use_generic_mul64bit: boolean;
begin begin
{$ifdef SPARC64} {$ifdef SPARC64}
result:=(cs_check_overflow in current_settings.localswitches); result:=needoverflowcheck;
{$else SPARC64} {$else SPARC64}
result:=inherited; result:=inherited;
{$endif SPARC64} {$endif SPARC64}

View File

@ -93,7 +93,9 @@ unit nx86add;
hl4 : tasmlabel; hl4 : tasmlabel;
r : Tregister; r : Tregister;
href : treference; href : treference;
overflowcheck: boolean;
begin begin
overflowcheck:=needoverflowcheck;
{ at this point, left.location.loc should be LOC_REGISTER } { at this point, left.location.loc should be LOC_REGISTER }
if right.location.loc=LOC_REGISTER then if right.location.loc=LOC_REGISTER then
begin begin
@ -152,7 +154,7 @@ unit nx86add;
if (op=A_ADD) and if (op=A_ADD) and
(right.location.loc=LOC_CONSTANT) and (right.location.loc=LOC_CONSTANT) and
(right.location.value=1) and (right.location.value=1) and
not(cs_check_overflow in current_settings.localswitches) and not overflowcheck and
UseIncDec then UseIncDec then
begin begin
emit_reg(A_INC,TCGSize2Opsize[opsize],left.location.register); emit_reg(A_INC,TCGSize2Opsize[opsize],left.location.register);
@ -161,7 +163,7 @@ unit nx86add;
if (op=A_SUB) and if (op=A_SUB) and
(right.location.loc=LOC_CONSTANT) and (right.location.loc=LOC_CONSTANT) and
(right.location.value=1) and (right.location.value=1) and
not(cs_check_overflow in current_settings.localswitches) and overflowcheck and
UseIncDec then UseIncDec then
begin begin
emit_reg(A_DEC,TCGSize2Opsize[opsize],left.location.register); emit_reg(A_DEC,TCGSize2Opsize[opsize],left.location.register);
@ -170,7 +172,7 @@ unit nx86add;
if (op=A_IMUL) and if (op=A_IMUL) and
(right.location.loc=LOC_CONSTANT) and (right.location.loc=LOC_CONSTANT) and
(ispowerof2(int64(right.location.value),power)) and (ispowerof2(int64(right.location.value),power)) and
not(cs_check_overflow in current_settings.localswitches) then overflowcheck then
begin begin
emit_const_reg(A_SHL,TCGSize2Opsize[opsize],power,left.location.register); emit_const_reg(A_SHL,TCGSize2Opsize[opsize],power,left.location.register);
end end
@ -178,7 +180,7 @@ unit nx86add;
(right.location.loc=LOC_CONSTANT) and (right.location.loc=LOC_CONSTANT) and
(right.location.value>1) and (ispowerof2(int64(right.location.value)-1,power)) and (right.location.value>1) and (ispowerof2(int64(right.location.value)-1,power)) and
(power in [1..3]) and (power in [1..3]) and
not(cs_check_overflow in current_settings.localswitches) then not overflowcheck then
begin begin
reference_reset_base(href,left.location.register,0,ctempposinvalid,0,[]); reference_reset_base(href,left.location.register,0,ctempposinvalid,0,[]);
href.index:=left.location.register; href.index:=left.location.register;
@ -209,7 +211,7 @@ unit nx86add;
{ is in unsigned VAR!! } { is in unsigned VAR!! }
if mboverflow then if mboverflow then
begin begin
if cs_check_overflow in current_settings.localswitches then if overflowcheck then
begin begin
current_asmdata.getjumplabel(hl4); current_asmdata.getjumplabel(hl4);
if unsigned then if unsigned then
@ -1466,9 +1468,7 @@ unit nx86add;
checkoverflow:= checkoverflow:=
checkoverflow and checkoverflow and
(left.resultdef.typ<>pointerdef) and needoverflowcheck;
(right.resultdef.typ<>pointerdef) and
(cs_check_overflow in current_settings.localswitches);
opsize:=def_cgsize(left.resultdef); opsize:=def_cgsize(left.resultdef);

View File

@ -52,7 +52,7 @@ interface
{ filter unsigned MUL opcode, which requires special handling. { filter unsigned MUL opcode, which requires special handling.
Note that when overflow checking is off, we can use IMUL instead. } Note that when overflow checking is off, we can use IMUL instead. }
if (nodetype=muln) and if (nodetype=muln) and
(cs_check_overflow in current_settings.localswitches) and needoverflowcheck and
(not(is_signed(left.resultdef)) or (not(is_signed(left.resultdef)) or
not(is_signed(right.resultdef))) then not(is_signed(right.resultdef))) then
begin begin
@ -126,7 +126,7 @@ interface
emit_ref(A_MUL,opsize,ref) emit_ref(A_MUL,opsize,ref)
else else
emit_reg(A_MUL,opsize,reg); emit_reg(A_MUL,opsize,reg);
if cs_check_overflow in current_settings.localswitches then if needoverflowcheck then
begin begin
current_asmdata.getjumplabel(hl4); current_asmdata.getjumplabel(hl4);
cg.a_jmp_flags(current_asmdata.CurrAsmList,F_AE,hl4); cg.a_jmp_flags(current_asmdata.CurrAsmList,F_AE,hl4);

11
tests/tbs/tb0658.pp Normal file
View File

@ -0,0 +1,11 @@
{$r+,q+}
procedure test(i: int64);
begin
if (i>0) and (i<$1fff) then
halt(1);
end;
begin
test(0);
end.