hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.java
changeset 46371 0337d0617e7b
parent 46344 694c102fd8ed
child 46393 d497d892ab11
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.java	Wed Apr 05 22:48:35 2017 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerLowerThanNode.java	Thu Apr 06 14:31:32 2017 -0700
@@ -28,13 +28,13 @@
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
+import org.graalvm.compiler.nodes.ConstantNode;
 import org.graalvm.compiler.nodes.LogicConstantNode;
 import org.graalvm.compiler.nodes.LogicNegationNode;
 import org.graalvm.compiler.nodes.LogicNode;
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.util.GraphUtil;
 
-import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.meta.TriState;
 
 /**
@@ -65,51 +65,9 @@
         if (synonym != null) {
             return synonym;
         }
-        if (forY.stamp() instanceof IntegerStamp) {
-            IntegerStamp yStamp = (IntegerStamp) forY.stamp();
-            if (forX.isConstant() && forX.asJavaConstant().asLong() == getOp().minValue(yStamp.getBits())) {
-                // MIN < y is the same as y != MIN
-                return LogicNegationNode.create(CompareNode.createCompareNode(Condition.EQ, forY, forX, tool.getConstantReflection()));
-            }
-            if (forY instanceof AddNode) {
-                AddNode addNode = (AddNode) forY;
-                ValueNode canonical = canonicalizeXLowerXPlusA(forX, addNode, false, true);
-                if (canonical != null) {
-                    return canonical;
-                }
-            }
-            if (forX instanceof AddNode) {
-                AddNode addNode = (AddNode) forX;
-                ValueNode canonical = canonicalizeXLowerXPlusA(forY, addNode, true, false);
-                if (canonical != null) {
-                    return canonical;
-                }
-            }
-        }
         return this;
     }
 
-    private ValueNode canonicalizeXLowerXPlusA(ValueNode forX, AddNode addNode, boolean negated, boolean strict) {
-        // x < x + a
-        Stamp succeedingXStamp;
-        if (addNode.getX() == forX && addNode.getY().stamp() instanceof IntegerStamp) {
-            succeedingXStamp = getOp().getSucceedingStampForXLowerXPlusA(negated, strict, (IntegerStamp) addNode.getY().stamp());
-        } else if (addNode.getY() == forX && addNode.getX().stamp() instanceof IntegerStamp) {
-            succeedingXStamp = getOp().getSucceedingStampForXLowerXPlusA(negated, strict, (IntegerStamp) addNode.getX().stamp());
-        } else {
-            return null;
-        }
-        succeedingXStamp = forX.stamp().join(succeedingXStamp);
-        if (succeedingXStamp.isEmpty()) {
-            return LogicConstantNode.contradiction();
-        }
-        /*
-         * since getSucceedingStampForXLowerXPlusA is only best effort,
-         * succeedingXStamp.equals(xStamp) does not imply tautology
-         */
-        return null;
-    }
-
     @Override
     public Stamp getSucceedingStampForX(boolean negated, Stamp xStampGeneric, Stamp yStampGeneric) {
         return getSucceedingStampForX(negated, !negated, xStampGeneric, yStampGeneric, getX(), getY());
@@ -196,10 +154,10 @@
 
         protected abstract Condition getCondition();
 
-        protected abstract IntegerLowerThanNode create(ValueNode x, ValueNode y);
+        protected abstract IntegerLowerThanNode createNode(ValueNode x, ValueNode y);
 
-        public LogicNode create(ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection) {
-            LogicNode result = CompareNode.tryConstantFold(getCondition(), x, y, constantReflection, false);
+        public LogicNode create(ValueNode x, ValueNode y) {
+            LogicNode result = CompareNode.tryConstantFoldPrimitive(getCondition(), x, y, false);
             if (result != null) {
                 return result;
             } else {
@@ -207,7 +165,7 @@
                 if (result != null) {
                     return result;
                 }
-                return create(x, y);
+                return createNode(x, y);
             }
         }
 
@@ -221,6 +179,73 @@
             } else if (fold.isFalse()) {
                 return LogicConstantNode.contradiction();
             }
+            if (forY.stamp() instanceof IntegerStamp) {
+                IntegerStamp yStamp = (IntegerStamp) forY.stamp();
+                int bits = yStamp.getBits();
+                if (forX.isJavaConstant() && !forY.isConstant()) {
+                    // bring the constant on the right
+                    long xValue = forX.asJavaConstant().asLong();
+                    if (xValue != maxValue(bits)) {
+                        // c < x <=> !(c >= x) <=> !(x <= c) <=> !(x < c + 1)
+                        return LogicNegationNode.create(create(forY, ConstantNode.forIntegerStamp(yStamp, xValue + 1)));
+                    }
+                }
+                if (forY.isJavaConstant()) {
+                    long yValue = forY.asJavaConstant().asLong();
+                    if (yValue == maxValue(bits)) {
+                        // x < MAX <=> x != MAX
+                        return LogicNegationNode.create(IntegerEqualsNode.create(forX, forY));
+                    }
+                    if (yValue == minValue(bits) + 1) {
+                        // x < MIN + 1 <=> x <= MIN <=> x == MIN
+                        return IntegerEqualsNode.create(forX, ConstantNode.forIntegerStamp(yStamp, minValue(bits)));
+                    }
+                } else if (forY instanceof AddNode) {
+                    AddNode addNode = (AddNode) forY;
+                    LogicNode canonical = canonicalizeXLowerXPlusA(forX, addNode, false, true);
+                    if (canonical != null) {
+                        return canonical;
+                    }
+                }
+                if (forX instanceof AddNode) {
+                    AddNode addNode = (AddNode) forX;
+                    LogicNode canonical = canonicalizeXLowerXPlusA(forY, addNode, true, false);
+                    if (canonical != null) {
+                        return canonical;
+                    }
+                }
+            }
+            return null;
+        }
+
+        private LogicNode canonicalizeXLowerXPlusA(ValueNode forX, AddNode addNode, boolean mirrored, boolean strict) {
+            // x < x + a
+            IntegerStamp succeedingXStamp;
+            boolean exact;
+            if (addNode.getX() == forX && addNode.getY().stamp() instanceof IntegerStamp) {
+                IntegerStamp aStamp = (IntegerStamp) addNode.getY().stamp();
+                succeedingXStamp = getSucceedingStampForXLowerXPlusA(mirrored, strict, aStamp);
+                exact = aStamp.lowerBound() == aStamp.upperBound();
+            } else if (addNode.getY() == forX && addNode.getX().stamp() instanceof IntegerStamp) {
+                IntegerStamp aStamp = (IntegerStamp) addNode.getX().stamp();
+                succeedingXStamp = getSucceedingStampForXLowerXPlusA(mirrored, strict, aStamp);
+                exact = aStamp.lowerBound() == aStamp.upperBound();
+            } else {
+                return null;
+            }
+            if (succeedingXStamp.join(forX.stamp()).isEmpty()) {
+                return LogicConstantNode.contradiction();
+            } else if (exact && !succeedingXStamp.isEmpty()) {
+                int bits = succeedingXStamp.getBits();
+                if (compare(lowerBound(succeedingXStamp), minValue(bits)) > 0) {
+                    assert upperBound(succeedingXStamp) == maxValue(bits);
+                    // x must be in [L..MAX] <=> x >= L <=> !(x < L)
+                    return LogicNegationNode.create(create(forX, ConstantNode.forIntegerStamp(succeedingXStamp, lowerBound(succeedingXStamp))));
+                } else if (compare(upperBound(succeedingXStamp), maxValue(bits)) < 0) {
+                    // x must be in [MIN..H] <=> x <= H <=> !(H < x)
+                    return LogicNegationNode.create(create(ConstantNode.forIntegerStamp(succeedingXStamp, upperBound(succeedingXStamp)), forX));
+                }
+            }
             return null;
         }
 
@@ -268,7 +293,7 @@
             return null;
         }
 
-        protected IntegerStamp getSucceedingStampForXLowerXPlusA(boolean negated, boolean strict, IntegerStamp a) {
+        protected IntegerStamp getSucceedingStampForXLowerXPlusA(boolean mirrored, boolean strict, IntegerStamp a) {
             int bits = a.getBits();
             long min = minValue(bits);
             long max = maxValue(bits);
@@ -286,7 +311,7 @@
              * This does not use upper/lowerBound from LowerOp because it's about the (signed)
              * addition not the comparison.
              */
-            if (negated) {
+            if (mirrored) {
                 if (a.contains(0)) {
                     // a may be zero
                     return a.unrestricted();