+ based on a patch by Laksen, optimize (v>=x) and (v<=y) into (v-x)<(y-x)

git-svn-id: trunk@39759 -
This commit is contained in:
florian 2018-09-16 13:09:36 +00:00
parent 8307e46e4b
commit a21397e356

View File

@ -376,9 +376,76 @@ implementation
function taddnode.simplify(forinline : boolean) : tnode;
function is_range_test(nodel, noder: taddnode; var value: tnode; var cl,cr: qword): boolean;
const
is_upper_test: array[ltn..gten] of boolean = (true,true,false,false);
inclusive_adjust: array[boolean,ltn..gten] of integer = ((1,0,-1,0),
(-1,0,1,0));
var
swapl, swapr: Boolean;
valuer: tnode;
t: QWord;
begin
result:=false;
swapl:=false;
swapr:=false;
if nodel.left.nodetype=ordconstn then
begin
swapl:=true;
cl:=tordconstnode(nodel.left).value.uvalue;
value:=nodel.right;
end
else if nodel.right.nodetype=ordconstn then
begin
cl:=tordconstnode(nodel.right).value.uvalue;
value:=nodel.left;
end
else
exit;
if is_signed(value.resultdef) then
exit;
if noder.left.nodetype=ordconstn then
begin
swapl:=true;
cr:=tordconstnode(noder.left).value.uvalue;
valuer:=noder.right;
end
else if noder.right.nodetype=ordconstn then
begin
cr:=tordconstnode(noder.right).value.uvalue;
valuer:=noder.left;
end
else
exit;
if not value.isequal(valuer) then
exit;
{ this could be simplified too, but probably never happens }
if (is_upper_test[nodel.nodetype] xor swapl)=(is_upper_test[noder.nodetype] xor swapr) then
exit;
cl:=cl+inclusive_adjust[swapl,nodel.nodetype];
cr:=cr+inclusive_adjust[swapr,noder.nodetype];
if is_upper_test[nodel.nodetype] xor swapl then
begin
t:=cl;
cl:=cr;
cr:=t;
end;
result:=true;
end;
var
t : tnode;
t , vl: tnode;
lt,rt : tnodetype;
hdef,
rd,ld : tdef;
rv,lv,v : tconstexprint;
rvd,lvd : bestreal;
@ -390,6 +457,7 @@ implementation
resultset : Tconstset;
res,
b : boolean;
cr, cl : qword;
begin
result:=nil;
l1:=0;
@ -984,6 +1052,25 @@ implementation
}
if is_boolean(left.resultdef) and is_boolean(right.resultdef) then
begin
{ transform unsigned comparisons of (v>=x) and (v<=y)
into (v-x)<(y-x)
}
if (nodetype=andn) and
(left.nodetype in [ltn,lten,gtn,gten]) and
(right.nodetype in [ltn,lten,gtn,gten]) and
(not might_have_sideeffects(left)) and
(not might_have_sideeffects(right)) and
is_range_test(taddnode(left),taddnode(right),vl,cl,cr) then
begin
hdef:=get_unsigned_inttype(vl.resultdef);
vl:=ctypeconvnode.create_internal(vl.getcopy,hdef);
result:=caddnode.create_internal(lten,
ctypeconvnode.create_internal(caddnode.create_internal(subn,vl,cordconstnode.create(cl,hdef,false)),hdef),
cordconstnode.create(cr-cl,hdef,false));
exit;
end;
{ even when short circuit boolean evaluation is active, this
optimization cannot be performed in case the node has
side effects, because this can change the result (e.g., in an