changeset 23006:9551cbb2b317

Canonicalize x - y < 0 to x < y when possible
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Tue, 17 Nov 2015 12:36:33 -0800
parents 6ec03d3b8369
children 029b961c2668
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java
diffstat 1 files changed, 26 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java	Tue Nov 17 19:02:13 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java	Tue Nov 17 12:36:33 2015 -0800
@@ -83,6 +83,20 @@
         return this;
     }
 
+    public static boolean subtractMayUnderflow(long x, long y, long minValue) {
+        long r = x - y;
+        // HD 2-12 Overflow iff the arguments have different signs and
+        // the sign of the result is different than the sign of x
+        return (((x ^ y) & (x ^ r)) < 0) || r <= minValue;
+    }
+
+    public static boolean subtractMayOverflow(long x, long y, long maxValue) {
+        long r = x - y;
+        // HD 2-12 Overflow iff the arguments have different signs and
+        // the sign of the result is different than the sign of x
+        return (((x ^ y) & (x ^ r)) < 0) || r > maxValue;
+    }
+
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
         ValueNode result = super.canonical(tool, forX, forY);
@@ -98,6 +112,18 @@
                 return new IntegerBelowNode(forX, forY);
             }
         }
+        if (forY.isConstant() && forY.asConstant().isDefaultForKind() && forX instanceof SubNode) {
+            // (x - y) < 0 when x - y is known not to underflow == x < y
+            SubNode sub = (SubNode) forX;
+            IntegerStamp xStamp = (IntegerStamp) sub.getX().stamp();
+            IntegerStamp yStamp = (IntegerStamp) sub.getY().stamp();
+            long minValue = CodeUtil.minValue(xStamp.getBits());
+            long maxValue = CodeUtil.maxValue(xStamp.getBits());
+
+            if (!subtractMayUnderflow(xStamp.lowerBound(), yStamp.upperBound(), minValue) && !subtractMayOverflow(xStamp.upperBound(), yStamp.lowerBound(), maxValue)) {
+                return new IntegerLessThanNode(sub.getX(), sub.getY());
+            }
+        }
         return this;
     }