changeset 12562:035474349265

Serveral fixes to StampTool.add and some tests
author Gilles Duboscq <duboscq@ssw.jku.at>
date Thu, 24 Oct 2013 20:15:49 +0200
parents d1f8d0538b79
children 6264d434aca2
files graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java
diffstat 2 files changed, 34 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Thu Oct 24 11:44:55 2013 +0200
+++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Thu Oct 24 20:15:49 2013 +0200
@@ -174,6 +174,13 @@
                         StampTool.add(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 1), StampFactory.forInteger(Kind.Long, Integer.MIN_VALUE, Integer.MAX_VALUE)));
         assertEquals(StampFactory.forInteger(Kind.Int, -2147483647, 31 - 2147483647),
                         StampTool.add(StampFactory.forInteger(Kind.Int, 0, 31), StampFactory.forInteger(Kind.Int, -2147483647, -2147483647)));
+
+        assertEquals(StampFactory.forInteger(Kind.Int, 0x8000007e, 0x8000007f, 0x8000007eL, 0x8000007fL),
+                        StampTool.add(StampFactory.forInteger(Kind.Int, 0x7ffffffe, 0x7fffffff, 0x7ffffffeL, 0x7fffffffL), StampFactory.forInteger(Kind.Int, 128, 128)));
+
+        assertEquals(StampFactory.forInteger(Kind.Long, -9223372036854775808L, 9223372036854775806L, 0, 0xfffffffffffffffeL),
+                        StampTool.add(StampFactory.forInteger(Kind.Long, -9223372036854775808L, 9223372036854775806L, 0, 0xfffffffffffffffeL),
+                                        StampFactory.forInteger(Kind.Long, -9223372036854775808L, 9223372036854775806L, 0, 0xfffffffffffffffeL)));
     }
 
     @Test
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Thu Oct 24 11:44:55 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Thu Oct 24 20:15:49 2013 +0200
@@ -114,13 +114,23 @@
         return StampFactory.forKind(kind);
     }
 
-    private static boolean addOverflows(long x, long y, Kind kind) {
+    private static boolean addOverflowsPositively(long x, long y, Kind kind) {
         long result = x + y;
         if (kind == Kind.Long) {
-            return ((x ^ result) & (y ^ result)) < 0;
+            return (~x & ~y & result) < 0;
         } else {
             assert kind == Kind.Int;
-            return result > Integer.MAX_VALUE || result < Integer.MIN_VALUE;
+            return result > Integer.MAX_VALUE;
+        }
+    }
+
+    private static boolean addOverflowsNegatively(long x, long y, Kind kind) {
+        long result = x + y;
+        if (kind == Kind.Long) {
+            return (x & y & ~result) < 0;
+        } else {
+            assert kind == Kind.Int;
+            return result < Integer.MIN_VALUE;
         }
     }
 
@@ -142,16 +152,22 @@
 
             long lowerBound;
             long upperBound;
-            if (addOverflows(stamp1.lowerBound(), stamp2.lowerBound(), kind) || addOverflows(stamp1.upperBound(), stamp2.upperBound(), kind)) {
+            boolean lowerOverflowsPositively = addOverflowsPositively(stamp1.lowerBound(), stamp2.lowerBound(), kind);
+            boolean upperOverflowsPositively = addOverflowsPositively(stamp1.upperBound(), stamp2.upperBound(), kind);
+            boolean lowerOverflowsNegatively = addOverflowsNegatively(stamp1.lowerBound(), stamp2.lowerBound(), kind);
+            boolean upperOverflowsNegatively = addOverflowsNegatively(stamp1.upperBound(), stamp2.upperBound(), kind);
+            if ((lowerOverflowsNegatively && !upperOverflowsNegatively) || (!lowerOverflowsNegatively && !lowerOverflowsPositively && upperOverflowsPositively)) {
                 lowerBound = kind.getMinValue();
                 upperBound = kind.getMaxValue();
             } else {
-                lowerBound = stamp1.lowerBound() + stamp2.lowerBound();
-                upperBound = stamp1.upperBound() + stamp2.upperBound();
+                lowerBound = signExtend(stamp1.lowerBound() + stamp2.lowerBound(), kind);
+                upperBound = signExtend(stamp1.upperBound() + stamp2.upperBound(), kind);
             }
             IntegerStamp limit = StampFactory.forInteger(kind, lowerBound, upperBound);
             newUpMask &= limit.upMask();
-            return new IntegerStamp(kind, lowerBound | newDownMask, signExtend(upperBound & newUpMask, kind), newDownMask, newUpMask);
+            upperBound = signExtend(upperBound & newUpMask, kind);
+            lowerBound |= newDownMask;
+            return new IntegerStamp(kind, lowerBound, upperBound, newDownMask, newUpMask);
         } catch (Throwable e) {
             throw new RuntimeException(stamp1 + " + " + stamp2, e);
         }
@@ -239,14 +255,15 @@
                 long lowerBound;
                 long upperBound;
                 long downMask = value.downMask() >>> shiftCount;
+                long upMask = value.upMask() >>> shiftCount;
                 if (value.lowerBound() < 0) {
                     lowerBound = downMask;
-                    upperBound = IntegerStamp.defaultMask(kind) >>> shiftCount;
+                    upperBound = upMask;
                 } else {
                     lowerBound = value.lowerBound() >>> shiftCount;
                     upperBound = value.upperBound() >>> shiftCount;
                 }
-                return new IntegerStamp(kind, lowerBound, upperBound, downMask, value.upMask() >>> shiftCount);
+                return new IntegerStamp(kind, lowerBound, upperBound, downMask, upMask);
             }
         }
         long mask = IntegerStamp.upMaskFor(kind, value.lowerBound(), value.upperBound());
@@ -310,7 +327,7 @@
     }
 
     private static long signExtend(long value, Kind valueKind) {
-        if (valueKind != Kind.Char && (value >>> (valueKind.getBitCount() - 1) & 1) == 1) {
+        if (valueKind != Kind.Char && valueKind != Kind.Long && (value >>> (valueKind.getBitCount() - 1) & 1) == 1) {
             return value | (-1L << valueKind.getBitCount());
         } else {
             return value;