changeset 16043:369a3f9d1ceb

Fix bug in inferred stamp of IntegerRemNode.
author Roland Schatz <roland.schatz@oracle.com>
date Thu, 05 Jun 2014 19:13:13 +0200
parents f546f40e1a6d
children 2662fb9c37e2
files graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotpath/HP_idea.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java
diffstat 2 files changed, 22 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotpath/HP_idea.java	Thu Jun 05 18:15:53 2014 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotpath/HP_idea.java	Thu Jun 05 19:13:13 2014 +0200
@@ -60,7 +60,7 @@
 
     /*
      * buildTestData
-     * 
+     *
      * Builds the data used for the test -- each time the test is run.
      */
 
@@ -115,7 +115,7 @@
 
     /*
      * calcEncryptKey
-     * 
+     *
      * Builds the 52 16-bit encryption subkeys Z[] from the user key and stores in 32-bit int array.
      * The routing corrects an error in the source code in the Schnier book. Basically, the sense of
      * the 7- and 9-bit shifts are reversed. It still works reversed, but would encrypted code would
@@ -169,7 +169,7 @@
 
     /*
      * calcDecryptKey
-     * 
+     *
      * Builds the 52 16-bit encryption subkeys DK[] from the encryption- subkeys Z[]. DK[] is a
      * 32-bit int array holding 16-bit values as unsigned.
      */
@@ -216,7 +216,7 @@
 
     /*
      * cipher_idea
-     * 
+     *
      * IDEA encryption/decryption algorithm. It processes plaintext in 64-bit blocks, one at a time,
      * breaking the block into four 16-bit unsigned subblocks. It goes through eight rounds of
      * processing using 6 new subkeys each time, plus four for last step. The source text is in
@@ -359,7 +359,7 @@
 
     /*
      * mul
-     * 
+     *
      * Performs multiplication, modulo (2**16)+1. This code is structured on the assumption that
      * untaken branches are cheaper than taken branches, and that the compiler doesn't schedule
      * branches. Java: Must work with 32-bit int and one 64-bit long to keep 16-bit values and their
@@ -369,7 +369,7 @@
      * zero whenever the result would zero, be 2**16. And if one of the multiplicands is 0, the
      * result is not zero, but (2**16) + 1 minus the other multiplicand (sort of an additive inverse
      * mod 0x10001).
-     * 
+     *
      * NOTE: The java conversion of this routine works correctly, but is half the speed of using
      * Java's modulus division function (%) on the multiplication with a 16-bit masking of the
      * result--running in the Symantec Caje IDE. So it's not called for now; the test uses Java %
@@ -380,7 +380,7 @@
      * private int mul(int a, int b) throws ArithmeticException { long p; // Large enough to catch
      * 16-bit multiply // without hitting sign bit. if (a != 0) { if (b != 0) { p = (long) a * b; b
      * = (int) p & 0xFFFF; // Lower 16 bits. a = (int) p >>> 16; // Upper 16 bits.
-     * 
+     *
      * return (b - a + (b < a ? 1 : 0) & 0xFFFF); } else return ((1 - a) & 0xFFFF); // If b = 0,
      * then same as // 0x10001 - a. } else // If a = 0, then return return((1 - b) & 0xFFFF); //
      * same as 0x10001 - b. }
@@ -388,15 +388,14 @@
 
     /*
      * inv
-     * 
+     *
      * Compute multiplicative inverse of x, modulo (2**16)+1 using extended Euclid's GCD (greatest
      * common divisor) algorithm. It is unrolled twice to avoid swapping the meaning of the
      * registers. And some subtracts are changed to adds. Java: Though it uses signed 32-bit ints,
      * the interpretation of the bits within is strictly unsigned 16-bit.
      */
 
-    @SuppressWarnings("static-method")
-    private int inv(int x) {
+    public int inv(int x) {
         int x2 = x;
         int t0, t1;
         int q, y;
@@ -440,7 +439,7 @@
 
     /*
      * freeTestData
-     * 
+     *
      * Nulls arrays and forces garbage collection to free up memory.
      */
 
@@ -462,4 +461,8 @@
         runTest("test");
     }
 
+    @Test
+    public void runInv() {
+        runTest("inv", 724);
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Thu Jun 05 18:15:53 2014 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Thu Jun 05 19:13:13 2014 +0200
@@ -114,25 +114,20 @@
 
     public static Stamp rem(IntegerStamp stamp1, IntegerStamp stamp2) {
         assert stamp1.getBits() == stamp2.getBits();
-        long magnitude; // the maximum absolute value of the result
+        // zero is always possible
+        long lowerBound = Math.min(stamp1.lowerBound(), 0);
+        long upperBound = Math.max(stamp1.upperBound(), 0);
+
+        long magnitude; // the maximum absolute value of the result, derived from stamp2
         if (stamp2.lowerBound() == IntegerStamp.defaultMinValue(stamp2.getBits())) {
             // Math.abs(...) - 1 does not work in this case
             magnitude = IntegerStamp.defaultMaxValue(stamp2.getBits());
         } else {
             magnitude = Math.max(Math.abs(stamp2.lowerBound()), Math.abs(stamp2.upperBound())) - 1;
         }
-        long lowerBound = Math.max(stamp1.lowerBound(), -magnitude);
-        if (stamp1.upperBound() > magnitude) {
-            // if the result can wrap around at the upper bound, it can reach any value between 0
-            // and magnitude
-            lowerBound = Math.min(lowerBound, 0);
-        }
-        long upperBound = Math.min(stamp1.upperBound(), magnitude);
-        if (stamp1.lowerBound() < -magnitude) {
-            // if the result can wrap around at the lower bound, it can reach any value between
-            // -magnitude and 0
-            upperBound = Math.max(upperBound, 0);
-        }
+        lowerBound = Math.max(lowerBound, -magnitude);
+        upperBound = Math.min(upperBound, magnitude);
+
         return StampFactory.forInteger(stamp1.getBits(), lowerBound, upperBound);
     }