Browse Source

+ more unary minus optimizations
* test extended

florian 3 years ago
parent
commit
69d5d648a9
2 changed files with 31 additions and 0 deletions
  1. 17 0
      compiler/nmat.pas
  2. 14 0
      tests/tbs/tb0685.pp

+ 17 - 0
compiler/nmat.pas

@@ -972,6 +972,23 @@ implementation
                 exit;
               end;
 
+            {
+              -(-left*right) or -(left*-right) => right*left
+
+              this operation is always valid as reals do not use a two's complement representation for negative
+              numbers, -real means just flip the sign bit
+            }
+            if (left.nodetype=muln) and ((taddnode(left).left.nodetype=unaryminusn)) then
+              begin
+                result:=caddnode.create(muln,taddnode(left).right.getcopy,tunaryminusnode(taddnode(left).left).left.getcopy);
+                exit;
+              end;
+            if (left.nodetype=muln) and ((taddnode(left).right.nodetype=unaryminusn)) then
+              begin
+                result:=caddnode.create(muln,taddnode(left).left.getcopy,tunaryminusnode(taddnode(left).right).left.getcopy);
+                exit;
+              end;
+
             { --node => node
               this operation is always valid as reals do not use a two's complement representation for negative
               numbers, -real means just flip the sign bit

+ 14 - 0
tests/tbs/tb0685.pp

@@ -44,5 +44,19 @@ begin
   if (d3<>0.0) or not(TDoubleRec(d3).Sign) then
     halt(7);
 
+  d1:=1.0;
+  d2:=2.0;
+  d3:=-(d2*-d1);
+  writeln(d3);
+  if (d3<>2.0) or (TDoubleRec(d3).Sign) then
+    halt(8);
+
+  d1:=1.0;
+  d2:=2.0;
+  d3:=-(-d2*d1);
+  writeln(d3);
+  if (d3<>2.0) or (TDoubleRec(d3).Sign) then
+    halt(9);
+
   writeln('ok');
 end.