changeset 10713:057154505878

fixed canonicalization bug (detected by Gilles) in binary logic nodes
author Doug Simon <doug.simon@oracle.com>
date Thu, 11 Jul 2013 20:58:54 +0200
parents 7f50d79c46f2
children 28dc33dc4565 7b5d7c42598b
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConjunctionNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConstantNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicDisjunctionNode.java
diffstat 3 files changed, 55 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConjunctionNode.java	Thu Jul 11 20:57:58 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConjunctionNode.java	Thu Jul 11 20:58:54 2013 +0200
@@ -26,7 +26,6 @@
 
 /**
  * This node is true if {@link #getX() x} <b>and</b> {@link #getY() y} are true.
- * 
  */
 public class LogicConjunctionNode extends LogicBinaryNode implements Canonicalizable {
 
@@ -43,7 +42,30 @@
         LogicNode x = getX();
         LogicNode y = getY();
         if (x == y) {
-            return x;
+            // @formatter:off
+            //  a &&  a = a
+            //  a && !a = false
+            // !a &&  a = false
+            // !a && !a = !a
+            // @formatter:on
+            if (isXNegated()) {
+                if (isYNegated()) {
+                    // !a && !a = !a
+                    negateUsages();
+                    return x;
+                } else {
+                    // !a && a = false
+                    return LogicConstantNode.contradiction(graph());
+                }
+            } else {
+                if (isYNegated()) {
+                    // a && !a = false
+                    return LogicConstantNode.contradiction(graph());
+                } else {
+                    // a && a = a
+                    return x;
+                }
+            }
         }
         if (x instanceof LogicConstantNode) {
             if (((LogicConstantNode) x).getValue() ^ isXNegated()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConstantNode.java	Thu Jul 11 20:57:58 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicConstantNode.java	Thu Jul 11 20:58:54 2013 +0200
@@ -26,8 +26,7 @@
 import com.oracle.graal.nodes.spi.*;
 
 /**
- * The {@code ConstantNode} represents a constant such as an integer value, long, float, object
- * reference, address, etc.
+ * The {@code LogicConstantNode} represents a boolean constant.
  */
 @NodeInfo(nameTemplate = "{p#value}")
 public class LogicConstantNode extends LogicNode implements LIRLowerable {
@@ -50,10 +49,16 @@
         return graph.unique(new LogicConstantNode(v));
     }
 
+    /**
+     * Gets a constant for {@code true}.
+     */
     public static LogicConstantNode tautology(Graph graph) {
         return forBoolean(true, graph);
     }
 
+    /**
+     * Gets a constant for {@code false}.
+     */
     public static LogicConstantNode contradiction(Graph graph) {
         return forBoolean(false, graph);
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicDisjunctionNode.java	Thu Jul 11 20:57:58 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicDisjunctionNode.java	Thu Jul 11 20:58:54 2013 +0200
@@ -43,7 +43,30 @@
         LogicNode x = getX();
         LogicNode y = getY();
         if (x == y) {
-            return x;
+            // @formatter:off
+            //  a ||  a = a
+            //  a || !a = true
+            // !a ||  a = true
+            // !a || !a = !a
+            // @formatter:on
+            if (isXNegated()) {
+                if (isYNegated()) {
+                    // !a || !a = !a
+                    negateUsages();
+                    return x;
+                } else {
+                    // !a || a = true
+                    return LogicConstantNode.tautology(graph());
+                }
+            } else {
+                if (isYNegated()) {
+                    // a || !a = true
+                    return LogicConstantNode.tautology(graph());
+                } else {
+                    // a || a = a
+                    return x;
+                }
+            }
         }
         if (x instanceof LogicConstantNode) {
             if (((LogicConstantNode) x).getValue() ^ isXNegated()) {