mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-22 04:29:29 +02:00
* simplify real expressions involving unary minus
+ test
This commit is contained in:
parent
12796d176d
commit
8cb92fd49a
@ -992,83 +992,128 @@ implementation
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ optimize operations with real constants, but only if fast math is switched on as
|
||||
the operations could change e.g. the sign of 0 so they cannot be optimized always
|
||||
}
|
||||
if (cs_opt_fastmath in current_settings.optimizerswitches) and
|
||||
is_real(resultdef) then
|
||||
if is_real(resultdef) then
|
||||
begin
|
||||
if lt=realconstn then
|
||||
if (nodetype=addn) then
|
||||
begin
|
||||
if (trealconstnode(left).value_real=0) and (nodetype in [addn,muln,subn,slashn]) then
|
||||
{ -left+right => right-left,
|
||||
this operation is always valid }
|
||||
if (left.nodetype=unaryminusn) then
|
||||
begin
|
||||
result:=caddnode.create(subn,right.getcopy,tunaryminusnode(left).left.getcopy);
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ left+(-right) => left-right,
|
||||
this operation is always valid }
|
||||
if (right.nodetype=unaryminusn) then
|
||||
begin
|
||||
result:=caddnode.create(subn,left.getcopy,tunaryminusnode(right).left.getcopy);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ left-(-right) => left+right,
|
||||
this operation is always valid }
|
||||
if (nodetype=subn) and (right.nodetype=unaryminusn) then
|
||||
begin
|
||||
result:=caddnode.create(addn,left.getcopy,tunaryminusnode(right).left.getcopy);
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ (-left)*(-right) => left*right,
|
||||
this operation is always valid }
|
||||
if (nodetype=muln) and (left.nodetype=unaryminusn) and (right.nodetype=unaryminusn) then
|
||||
begin
|
||||
result:=caddnode.create(muln,tunaryminusnode(left).left.getcopy,tunaryminusnode(right).left.getcopy);
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ (-left)/(-right) => left/right,
|
||||
this operation is always valid }
|
||||
if (nodetype=slashn) and (left.nodetype=unaryminusn) and (right.nodetype=unaryminusn) then
|
||||
begin
|
||||
result:=caddnode.create(slashn,tunaryminusnode(left).left.getcopy,tunaryminusnode(right).left.getcopy);
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ optimize operations with real constants, but only if fast math is switched on as
|
||||
the operations could change e.g. the sign of 0 so they cannot be optimized always
|
||||
}
|
||||
if is_real(resultdef) then
|
||||
begin
|
||||
if lt=realconstn then
|
||||
begin
|
||||
if (trealconstnode(left).value_real=0) and (nodetype in [addn,muln,subn,slashn]) then
|
||||
begin
|
||||
case nodetype of
|
||||
addn:
|
||||
begin
|
||||
result:=right.getcopy;
|
||||
exit;
|
||||
end;
|
||||
slashn,
|
||||
muln:
|
||||
if not(might_have_sideeffects(right,[mhs_exceptions])) then
|
||||
begin
|
||||
result:=left.getcopy;
|
||||
exit;
|
||||
end;
|
||||
subn:
|
||||
begin
|
||||
result:=ctypeconvnode.create_internal(cunaryminusnode.create(right.getcopy),right.resultdef);
|
||||
exit;
|
||||
end;
|
||||
else
|
||||
Internalerror(2020060801);
|
||||
end;
|
||||
end
|
||||
else if (trealconstnode(left).value_real=1) and (nodetype=muln) then
|
||||
begin
|
||||
result:=right.getcopy;
|
||||
exit;
|
||||
end;
|
||||
end
|
||||
else if rt=realconstn then
|
||||
begin
|
||||
if (trealconstnode(right).value_real=0) and (nodetype in [addn,muln,subn]) then
|
||||
begin
|
||||
case nodetype of
|
||||
subn,
|
||||
addn:
|
||||
begin
|
||||
result:=left.getcopy;
|
||||
exit;
|
||||
end;
|
||||
muln:
|
||||
if not(might_have_sideeffects(left,[mhs_exceptions])) then
|
||||
begin
|
||||
result:=right.getcopy;
|
||||
exit;
|
||||
end;
|
||||
else
|
||||
Internalerror(2020060802);
|
||||
end;
|
||||
end
|
||||
else if (trealconstnode(right).value_real=1) and (nodetype in [muln,slashn]) then
|
||||
begin
|
||||
result:=left.getcopy;
|
||||
exit;
|
||||
end;
|
||||
end
|
||||
{ optimize a/a and a-a }
|
||||
else if (cs_opt_level2 in current_settings.optimizerswitches) and (nodetype in [slashn,subn]) and
|
||||
left.isequal(right) and not(might_have_sideeffects(left,[mhs_exceptions])) then
|
||||
begin
|
||||
case nodetype of
|
||||
addn:
|
||||
begin
|
||||
result:=right.getcopy;
|
||||
exit;
|
||||
end;
|
||||
slashn,
|
||||
muln:
|
||||
if not(might_have_sideeffects(right,[mhs_exceptions])) then
|
||||
begin
|
||||
result:=left.getcopy;
|
||||
exit;
|
||||
end;
|
||||
subn:
|
||||
begin
|
||||
result:=ctypeconvnode.create_internal(cunaryminusnode.create(right.getcopy),right.resultdef);
|
||||
exit;
|
||||
end;
|
||||
result:=crealconstnode.create(0,left.resultdef);
|
||||
slashn:
|
||||
result:=crealconstnode.create(1,left.resultdef);
|
||||
else
|
||||
Internalerror(2020060801);
|
||||
Internalerror(2020060901);
|
||||
end;
|
||||
end
|
||||
else if (trealconstnode(left).value_real=1) and (nodetype=muln) then
|
||||
begin
|
||||
result:=right.getcopy;
|
||||
exit;
|
||||
end;
|
||||
end
|
||||
else if rt=realconstn then
|
||||
begin
|
||||
if (trealconstnode(right).value_real=0) and (nodetype in [addn,muln,subn]) then
|
||||
begin
|
||||
case nodetype of
|
||||
subn,
|
||||
addn:
|
||||
begin
|
||||
result:=left.getcopy;
|
||||
exit;
|
||||
end;
|
||||
muln:
|
||||
if not(might_have_sideeffects(left,[mhs_exceptions])) then
|
||||
begin
|
||||
result:=right.getcopy;
|
||||
exit;
|
||||
end;
|
||||
else
|
||||
Internalerror(2020060802);
|
||||
end;
|
||||
end
|
||||
else if (trealconstnode(right).value_real=1) and (nodetype in [muln,slashn]) then
|
||||
begin
|
||||
result:=left.getcopy;
|
||||
exit;
|
||||
end;
|
||||
end
|
||||
{ optimize a/a and a-a }
|
||||
else if (cs_opt_level2 in current_settings.optimizerswitches) and (nodetype in [slashn,subn]) and
|
||||
left.isequal(right) and not(might_have_sideeffects(left,[mhs_exceptions])) then
|
||||
begin
|
||||
case nodetype of
|
||||
subn:
|
||||
result:=crealconstnode.create(0,left.resultdef);
|
||||
slashn:
|
||||
result:=crealconstnode.create(1,left.resultdef);
|
||||
else
|
||||
Internalerror(2020060901);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
35
tests/tbs/tb0685.pp
Normal file
35
tests/tbs/tb0685.pp
Normal file
@ -0,0 +1,35 @@
|
||||
{ %OPT=-O- }
|
||||
|
||||
var
|
||||
d1,d2,d3 : double;
|
||||
|
||||
begin
|
||||
d1:=0.0;
|
||||
d2:=-0.0;
|
||||
d3:=-d1+d2;
|
||||
writeln(d3);
|
||||
if (d3<>0.0) or not(TDoubleRec(d3).Sign) then
|
||||
halt(1);
|
||||
d3:=d2+-d1;
|
||||
writeln(d3);
|
||||
if (d3<>0.0) or not(TDoubleRec(d3).Sign) then
|
||||
halt(2);
|
||||
d3:=d2--d1;
|
||||
writeln(d3);
|
||||
if (d3<>0.0) or (TDoubleRec(d3).Sign) then
|
||||
halt(3);
|
||||
|
||||
d1:=1.0;
|
||||
d2:=1.0;
|
||||
d3:=-d2*-d1;
|
||||
writeln(d3);
|
||||
if (d3<>1.0) or (TDoubleRec(d3).Sign) then
|
||||
halt(4);
|
||||
|
||||
d3:=-d2/-d1;
|
||||
writeln(d3);
|
||||
if (d3<>1.0) or (TDoubleRec(d3).Sign) then
|
||||
halt(5);
|
||||
|
||||
writeln('ok');
|
||||
end.
|
Loading…
Reference in New Issue
Block a user