mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-07 13:30:33 +02:00
* 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:
parent
c70f2c63cd
commit
ce598c15ec
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
11
tests/tbs/tb0658.pp
Normal 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.
|
Loading…
Reference in New Issue
Block a user