changeset 12677:e53aa17b8fdf

Fix some more problems in StampTool.add and simplify the overflow condition Add more tests to IntegerStampTest and split them into independent methods
author Gilles Duboscq <duboscq@ssw.jku.at>
date Tue, 05 Nov 2013 15:46:01 +0100
parents 524afdbe0612
children 3332295624ec 3affe68ddb50
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, 111 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Tue Nov 05 15:44:30 2013 +0100
+++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java	Tue Nov 05 15:46:01 2013 +0100
@@ -167,23 +167,93 @@
 
     @Test
     public void testNot() {
-        assertEquals(new IntegerStamp(Kind.Int, -11, -1, 0xfffffff0L, 0xffffffffL), StampTool.not(new IntegerStamp(Kind.Int, 0, 10, 0, 0xf)));
+        assertEquals(new IntegerStamp(Kind.Int, -11, -1, 0xffff_fff0L, 0xffff_ffffL), StampTool.not(new IntegerStamp(Kind.Int, 0, 10, 0, 0xf)));
+    }
+
+    @Test
+    public void testAddIntSimple() {
+        assertEquals(StampFactory.forInteger(Kind.Int, 0, 30, 0, 31), StampTool.add(StampFactory.forInteger(Kind.Int, 0, 10), StampFactory.forInteger(Kind.Int, 0, 20)));
+    }
+
+    @Test
+    public void testAddNegativeOverFlowInt1() {
+        assertEquals(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0xffff_ffffL),
+                        StampTool.add(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, 0), StampFactory.forInteger(Kind.Int, -1, 0)));
+    }
+
+    @Test
+    public void testAddNegativeOverFlowInt2() {
+        assertEquals(StampFactory.forInteger(Kind.Int, Integer.MAX_VALUE - 2, Integer.MAX_VALUE, 0x7fff_fffcL, 0x7fff_ffffL),
+                        StampTool.add(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MIN_VALUE + 1), StampFactory.forInteger(Kind.Int, -3, -2)));
+    }
+
+    @Test
+    public void testAddPositiveOverFlowInt1() {
+        assertEquals(StampFactory.forKind(Kind.Int), StampTool.add(StampFactory.forInteger(Kind.Int, 0, 1), StampFactory.forInteger(Kind.Int, 0, Integer.MAX_VALUE)));
+    }
+
+    @Test
+    public void testAddPositiveOverFlowInt2() {
+        assertEquals(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MIN_VALUE + 2),
+                        StampTool.add(StampFactory.forInteger(Kind.Int, Integer.MAX_VALUE - 1, Integer.MAX_VALUE), StampFactory.forInteger(Kind.Int, 2, 3)));
+    }
+
+    @Test
+    public void testAddOverFlowsInt() {
+        assertEquals(StampFactory.forKind(Kind.Int), StampTool.add(StampFactory.forInteger(Kind.Int, -1, 1), StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, Integer.MAX_VALUE)));
+    }
+
+    @Test
+    public void testAddLongSimple() {
+        assertEquals(StampFactory.forInteger(Kind.Long, 0, 30, 0, 31), StampTool.add(StampFactory.forInteger(Kind.Long, 0, 10), StampFactory.forInteger(Kind.Long, 0, 20)));
     }
 
     @Test
-    public void testAdd() {
-        assertEquals(StampFactory.forInteger(Kind.Int, 0, 30), StampTool.add(StampFactory.forInteger(Kind.Int, 0, 10), StampFactory.forInteger(Kind.Int, 0, 20)));
-        assertEquals(StampFactory.forKind(Kind.Long),
+    public void testAddNegativOverFlowLong1() {
+        assertEquals(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE, 0, 0xffff_ffff_ffff_ffffL),
                         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)));
+    }
+
+    @Test
+    public void testAddNegativeOverFlowLong2() {
+        assertEquals(StampFactory.forInteger(Kind.Long, Long.MAX_VALUE - 2, Long.MAX_VALUE),
+                        StampTool.add(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 1), StampFactory.forInteger(Kind.Long, -3, -2)));
+    }
+
+    @Test
+    public void testAddPositiveOverFlowLong1() {
+        assertEquals(StampFactory.forKind(Kind.Long), StampTool.add(StampFactory.forInteger(Kind.Long, 0, 1), StampFactory.forInteger(Kind.Long, 0, Long.MAX_VALUE)));
+    }
+
+    @Test
+    public void testAddPositiveOverFlowLong2() {
+        assertEquals(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MIN_VALUE + 2),
+                        StampTool.add(StampFactory.forInteger(Kind.Long, Long.MAX_VALUE - 1, Long.MAX_VALUE), StampFactory.forInteger(Kind.Long, 2, 3)));
+    }
 
-        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)));
+    @Test
+    public void testAddOverFlowsLong() {
+        assertEquals(StampFactory.forKind(Kind.Long), StampTool.add(StampFactory.forInteger(Kind.Long, -1, 1), StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE)));
+    }
+
+    @Test
+    public void testAdd1() {
+        assertEquals(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE + 1, 31 + (Integer.MIN_VALUE + 1)),
+                        StampTool.add(StampFactory.forInteger(Kind.Int, 0, 31), StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE + 1, Integer.MIN_VALUE + 1)));
+    }
 
-        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
+    public void testAdd2() {
+        assertEquals(StampFactory.forInteger(Kind.Int, 0x8000_007e, 0x8000_007f, 0x8000_007eL, 0x8000_007fL),
+                        StampTool.add(StampFactory.forInteger(Kind.Int, 0x7fff_fffe, 0x7fff_ffff, 0x7fff_fffeL, 0x7ffff_fffL), StampFactory.forInteger(Kind.Int, 128, 128)));
+    }
+
+    @Test
+    public void testAdd3() {
+        assertEquals(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE - 1, 0, 0xffff_ffff_ffff_fffeL),
+                        StampTool.add(StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE - 1, 0, 0xffff_ffff_ffff_fffeL),
+                                        StampFactory.forInteger(Kind.Long, Long.MIN_VALUE, Long.MAX_VALUE - 1, 0, 0xffff_ffff_ffff_fffeL)));
+
     }
 
     @Test
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Tue Nov 05 15:44:30 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Tue Nov 05 15:46:01 2013 +0100
@@ -135,42 +135,39 @@
     }
 
     public static IntegerStamp add(IntegerStamp stamp1, IntegerStamp stamp2) {
-        try {
-            if (stamp1.isUnrestricted() || stamp2.isUnrestricted()) {
-                return (IntegerStamp) StampFactory.forKind(stamp1.kind());
-            }
-            Kind kind = stamp1.kind();
-            assert stamp1.kind() == stamp2.kind();
-            long defaultMask = IntegerStamp.defaultMask(kind);
-            long variableBits = (stamp1.downMask() ^ stamp1.upMask()) | (stamp2.downMask() ^ stamp2.upMask());
-            long variableBitsWithCarry = variableBits | (carryBits(stamp1.downMask(), stamp2.downMask()) ^ carryBits(stamp1.upMask(), stamp2.upMask()));
-            long newDownMask = (stamp1.downMask() + stamp2.downMask()) & ~variableBitsWithCarry;
-            long newUpMask = (stamp1.downMask() + stamp2.downMask()) | variableBitsWithCarry;
+        if (stamp1.isUnrestricted() || stamp2.isUnrestricted()) {
+            return (IntegerStamp) StampFactory.forKind(stamp1.kind());
+        }
+        Kind kind = stamp1.kind();
+        assert stamp1.kind() == stamp2.kind();
+        long defaultMask = IntegerStamp.defaultMask(kind);
+        long variableBits = (stamp1.downMask() ^ stamp1.upMask()) | (stamp2.downMask() ^ stamp2.upMask());
+        long variableBitsWithCarry = variableBits | (carryBits(stamp1.downMask(), stamp2.downMask()) ^ carryBits(stamp1.upMask(), stamp2.upMask()));
+        long newDownMask = (stamp1.downMask() + stamp2.downMask()) & ~variableBitsWithCarry;
+        long newUpMask = (stamp1.downMask() + stamp2.downMask()) | variableBitsWithCarry;
 
-            newDownMask &= defaultMask;
-            newUpMask &= defaultMask;
+        newDownMask &= defaultMask;
+        newUpMask &= defaultMask;
 
-            long lowerBound;
-            long upperBound;
-            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 = signExtend(stamp1.lowerBound() + stamp2.lowerBound(), kind);
-                upperBound = signExtend(stamp1.upperBound() + stamp2.upperBound(), kind);
-            }
-            IntegerStamp limit = StampFactory.forInteger(kind, lowerBound, upperBound);
-            newUpMask &= limit.upMask();
-            upperBound = signExtend(upperBound & newUpMask, kind);
-            lowerBound |= newDownMask;
-            return new IntegerStamp(kind, lowerBound, upperBound, newDownMask, newUpMask);
-        } catch (Throwable e) {
-            throw new RuntimeException(stamp1 + " + " + stamp2, e);
+        long lowerBound;
+        long upperBound;
+        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) || (!lowerOverflowsPositively && upperOverflowsPositively)) {
+            lowerBound = kind.getMinValue();
+            upperBound = kind.getMaxValue();
+        } else {
+            lowerBound = signExtend((stamp1.lowerBound() + stamp2.lowerBound()) & defaultMask, kind);
+            upperBound = signExtend((stamp1.upperBound() + stamp2.upperBound()) & defaultMask, kind);
         }
+        IntegerStamp limit = StampFactory.forInteger(kind, lowerBound, upperBound);
+        newUpMask &= limit.upMask();
+        upperBound = signExtend(upperBound & newUpMask, kind);
+        newDownMask |= limit.downMask();
+        lowerBound |= newDownMask;
+        return new IntegerStamp(kind, lowerBound, upperBound, newDownMask, newUpMask);
     }
 
     public static Stamp sub(IntegerStamp stamp1, IntegerStamp stamp2) {