# HG changeset patch # User Lukas Stadler # Date 1400595436 -7200 # Node ID 308cedd2aaa2491f9be799cd60c3d6329d2a30d7 # Parent c74c34976c47cdfee348ff9b1d8079d345a94467 better stamps for IntegerRemNode diff -r c74c34976c47 -r 308cedd2aaa2 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Tue May 20 15:28:53 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java Tue May 20 16:17:16 2014 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; @NodeInfo(shortName = "%") public class IntegerRemNode extends FixedBinaryNode implements Canonicalizable, Lowerable, LIRLowerable { @@ -37,6 +38,11 @@ } @Override + public boolean inferStamp() { + return updateStamp(StampTool.rem(x().stamp(), y().stamp())); + } + + @Override public Node canonical(CanonicalizerTool tool) { if (x().isConstant() && y().isConstant()) { long y = y().asConstant().asLong(); diff -r c74c34976c47 -r 308cedd2aaa2 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 Tue May 20 15:28:53 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Tue May 20 16:17:16 2014 +0200 @@ -105,6 +105,37 @@ return stamp1.unrestricted(); } + public static Stamp rem(Stamp stamp1, Stamp stamp2) { + if (stamp1 instanceof IntegerStamp && stamp2 instanceof IntegerStamp) { + return rem((IntegerStamp) stamp1, (IntegerStamp) stamp2); + } + return StampFactory.illegal(); + } + + public static Stamp rem(IntegerStamp stamp1, IntegerStamp stamp2) { + assert stamp1.getBits() == stamp2.getBits(); + long magnitude; // the maximum absolute value of the result + 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); + } + return StampFactory.forInteger(stamp1.getBits(), lowerBound, upperBound); + } + private static boolean addOverflowsPositively(long x, long y, int bits) { long result = x + y; if (bits == 64) {