Browse Source

+ apply unary minus optimizations also to /
* test extended

florian 3 years ago
parent
commit
5abfe21f39
2 changed files with 32 additions and 1 deletions
  1. 18 1
      compiler/nmat.pas
  2. 14 0
      tests/tbs/tb0685.pp

+ 18 - 1
compiler/nmat.pas

@@ -980,7 +980,7 @@ implementation
             }
             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);
+                result:=caddnode.create(muln,tunaryminusnode(taddnode(left).left).left.getcopy,taddnode(left).right.getcopy);
                 exit;
               end;
             if (left.nodetype=muln) and ((taddnode(left).right.nodetype=unaryminusn)) then
@@ -989,6 +989,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=slashn) and ((taddnode(left).left.nodetype=unaryminusn)) then
+              begin
+                result:=caddnode.create(slashn,tunaryminusnode(taddnode(left).left).left.getcopy,taddnode(left).right.getcopy);
+                exit;
+              end;
+            if (left.nodetype=slashn) and ((taddnode(left).right.nodetype=unaryminusn)) then
+              begin
+                result:=caddnode.create(slashn,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

@@ -58,5 +58,19 @@ begin
   if (d3<>2.0) or (TDoubleRec(d3).Sign) then
     halt(9);
 
+  d1:=1.0;
+  d2:=2.0;
+  d3:=-(d2/-d1);
+  writeln(d3);
+  if (d3<>2.0) or (TDoubleRec(d3).Sign) then
+    halt(10);
+
+  d1:=1.0;
+  d2:=2.0;
+  d3:=-(-d2/d1);
+  writeln(d3);
+  if (d3<>2.0) or (TDoubleRec(d3).Sign) then
+    halt(11);
+
   writeln('ok');
 end.