* 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/tb0656.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/tb610.pp svneol=native#text/pascal
tests/tbs/tb613.pp svneol=native#text/plain

View File

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

View File

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

View File

@ -315,7 +315,7 @@ interface
{ is in unsigned VAR!! }
if mboverflow then
begin
if cs_check_overflow in current_settings.localswitches then
if needoverflowcheck then
begin
current_asmdata.getjumplabel(hl4);
if unsigned then
@ -1002,6 +1002,7 @@ interface
ref:Treference;
use_ref:boolean;
hl4 : tasmlabel;
overflowcheck: boolean;
const
asmops: array[boolean] of tasmop = (A_IMUL, A_MUL);
@ -1012,10 +1013,12 @@ interface
pass_left_right;
overflowcheck:=needoverflowcheck;
{ 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
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
unsigned:=true;
@ -1048,7 +1051,7 @@ interface
emit_ref(asmops[unsigned],S_W,ref)
else
emit_reg(asmops[unsigned],S_W,reg);
if (cs_check_overflow in current_settings.localswitches) and
if overflowcheck and
{ 16->32 bit cannot overflow }
(not is_32bitint(resultdef)) then
begin

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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