浏览代码

* do not apply the (a and b) or (c and not(b)) into c xor ((c xor a) and b) optimziation if short boolean evaluation is used, should resolve #38576
* improved test

git-svn-id: trunk@48884 -

florian 4 年之前
父节点
当前提交
62bd0068b6
共有 2 个文件被更改,包括 120 次插入31 次删除
  1. 1 0
      compiler/nadd.pas
  2. 119 31
      tests/test/tandorandnot1.pp

+ 1 - 0
compiler/nadd.pas

@@ -1715,6 +1715,7 @@ implementation
              (left.resultdef.typ=orddef) and
              (left.nodetype=andn) and
              (right.nodetype=andn) and
+             not(is_boolean(resultdef) or (cs_full_boolean_eval in current_settings.localswitches)) and
              { this test is not needed but it speeds up the test and allows to bail out early }
              ((taddnode(left).left.nodetype=notn) or (taddnode(left).right.nodetype=notn) or
               (taddnode(right).left.nodetype=notn) or (taddnode(right).right.nodetype=notn)

+ 119 - 31
tests/test/tandorandnot1.pp

@@ -1,34 +1,122 @@
 { test (a and b) or (c and not(b)) into c xor ((c xor a) and b) optimization with random values }
-var
-  i,a,b,c,_a,_b,_c : word;
+procedure test_word;
+  var
+    i,a,b,c,_a,_b,_c : word;
+  begin
+    for i:=1 to 1000 do
+      begin
+        a:=random(65536);
+        _a:=a;
+        b:=random(65536);
+        _b:=b;
+        c:=random(65536);
+        _c:=c;
+        if (a and b) or (c and not(b))<>_c xor ((_c xor _a) and _b) then
+          begin
+            writeln('Error: ','a=',a,'b=',b,'c=',c);
+            halt(1);
+          end;
+        if (a and b) or (not(b) and c)<>_c xor ((_c xor _a) and _b) then
+          begin
+            writeln('Error: ','a=',a,'b=',b,'c=',c);
+            halt(1);
+          end;
+        if (not(b) and c) or (a and b)<>_c xor ((_c xor _a) and _b) then
+          begin
+            writeln('Error: ','a=',a,'b=',b,'c=',c);
+            halt(1);
+          end;
+        if (not(b) and c) or (b and a)<>_c xor ((_c xor _a) and _b) then
+          begin
+            writeln('Error: ','a=',a,'b=',b,'c=',c);
+            halt(1);
+          end;
+      end;
+  end;
+
+procedure test_boolean;
+  var
+    i : word;
+    a,b,c,_a,_b,_c : boolean;
+  begin
+    for i:=1 to 100 do
+      begin
+        a:=boolean(random(1));
+        _a:=a;
+        b:=boolean(random(1));
+        _b:=b;
+        c:=boolean(random(1));
+        _c:=c;
+        if (a and b) or (c and not(b))<>_c xor ((_c xor _a) and _b) then
+          begin
+            writeln('Error: ','a=',a,'b=',b,'c=',c);
+            halt(11);
+          end;
+        if (a and b) or (not(b) and c)<>_c xor ((_c xor _a) and _b) then
+          begin
+            writeln('Error: ','a=',a,'b=',b,'c=',c);
+            halt(11);
+          end;
+        if (not(b) and c) or (a and b)<>_c xor ((_c xor _a) and _b) then
+          begin
+            writeln('Error: ','a=',a,'b=',b,'c=',c);
+            halt(11);
+          end;
+        if (not(b) and c) or (b and a)<>_c xor ((_c xor _a) and _b) then
+          begin
+            writeln('Error: ','a=',a,'b=',b,'c=',c);
+            halt(11);
+          end;
+      end;
+  end;
+
+
+procedure test_pboolean;
+  var
+    i : word;
+    a,b,c : pboolean;
+    _a,_b,_c : boolean;
+  begin
+    new(a);
+    new(b);
+    for i:=1 to 100 do
+      begin
+        a^:=true;
+        _a:=a^;
+        b^:=true;
+        _b:=b^;
+        c:=nil;  
+        { c should not matter in this case }      
+        _c:=boolean(random(1));
+        if (a^ and b^) or (c^ and not(b^))<>_c xor ((_c xor _a) and _b) then
+          begin
+            writeln('Error: ','a=',a^,'b=',b^,'c=',c^);
+            halt(21);
+          end;
+        if (a^ and b^) or (not(b^) and c^)<>_c xor ((_c xor _a) and _b) then
+          begin
+            writeln('Error: ','a=',a^,'b=',b^,'c=',c^);
+            halt(21);
+          end;
+        if (not(b^) and c^) or (a^ and b^)<>_c xor ((_c xor _a) and _b) then
+          begin
+            writeln('Error: ','a=',a^,'b=',b^,'c=',c^);
+            halt(21);
+          end;
+        if (not(b^) and c^) or (b^ and a^)<>_c xor ((_c xor _a) and _b) then
+          begin
+            writeln('Error: ','a=',a^,'b=',b^,'c=',c^);
+            halt(21);
+          end;
+      end;
+    dispose(a);
+    dispose(b);
+  end;
+
+
 begin
-  for i:=1 to 1000 do
-    begin
-      a:=random(65536);
-      _a:=a;
-      b:=random(65536);
-      _b:=b;
-      c:=random(65536);
-      _c:=c;
-      if (a and b) or (c and not(b))<>_c xor ((_c xor _a) and _b) then
-        begin
-          writeln('Error: ','a=',a,'b=',b,'c=',c);
-          halt(1);
-        end;
-      if (a and b) or (not(b) and c)<>_c xor ((_c xor _a) and _b) then
-        begin
-          writeln('Error: ','a=',a,'b=',b,'c=',c);
-          halt(1);
-        end;
-      if (not(b) and c) or (a and b)<>_c xor ((_c xor _a) and _b) then
-        begin
-          writeln('Error: ','a=',a,'b=',b,'c=',c);
-          halt(1);
-        end;
-      if (not(b) and c) or (b and a)<>_c xor ((_c xor _a) and _b) then
-        begin
-          writeln('Error: ','a=',a,'b=',b,'c=',c);
-          halt(1);
-        end;
-    end;
+  test_word;
+  test_boolean;
+  test_pboolean;
 end.
+