# HG changeset patch # User Roland Schatz # Date 1401988393 -7200 # Node ID 369a3f9d1ceb2dd92fb8bf569f0701f7bda32354 # Parent f546f40e1a6d0b79c9fa6bbd8453a14707c86b33 Fix bug in inferred stamp of IntegerRemNode. diff -r f546f40e1a6d -r 369a3f9d1ceb graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/hotpath/HP_idea.java --- 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); + } } diff -r f546f40e1a6d -r 369a3f9d1ceb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java --- 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); }