--- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedDivNode.java 2017-11-03 23:57:11.236556434 -0700 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedDivNode.java 2017-11-03 23:57:10.909541801 -0700 @@ -63,29 +63,9 @@ return ConstantNode.forIntegerStamp(stamp(), forX.asJavaConstant().asLong() / y); } else if (forY.isConstant()) { long c = forY.asJavaConstant().asLong(); - if (c == 1) { - return forX; - } - if (c == -1) { - return NegateNode.create(forX); - } - long abs = Math.abs(c); - if (CodeUtil.isPowerOf2(abs) && forX.stamp() instanceof IntegerStamp) { - ValueNode dividend = forX; - IntegerStamp stampX = (IntegerStamp) forX.stamp(); - int log2 = CodeUtil.log2(abs); - // no rounding if dividend is positive or if its low bits are always 0 - if (stampX.canBeNegative() || (stampX.upMask() & (abs - 1)) != 0) { - int bits = PrimitiveStamp.getBits(stamp()); - RightShiftNode sign = new RightShiftNode(forX, ConstantNode.forInt(bits - 1)); - UnsignedRightShiftNode round = new UnsignedRightShiftNode(sign, ConstantNode.forInt(bits - log2)); - dividend = BinaryArithmeticNode.add(dividend, round); - } - RightShiftNode shift = new RightShiftNode(dividend, ConstantNode.forInt(log2)); - if (c < 0) { - return NegateNode.create(shift); - } - return shift; + ValueNode v = canonical(forX, c); + if (v != null) { + return v; } } @@ -113,6 +93,34 @@ return this; } + public static ValueNode canonical(ValueNode forX, long c) { + if (c == 1) { + return forX; + } + if (c == -1) { + return NegateNode.create(forX); + } + long abs = Math.abs(c); + if (CodeUtil.isPowerOf2(abs) && forX.stamp() instanceof IntegerStamp) { + ValueNode dividend = forX; + IntegerStamp stampX = (IntegerStamp) forX.stamp(); + int log2 = CodeUtil.log2(abs); + // no rounding if dividend is positive or if its low bits are always 0 + if (stampX.canBeNegative() || (stampX.upMask() & (abs - 1)) != 0) { + int bits = PrimitiveStamp.getBits(forX.stamp()); + RightShiftNode sign = new RightShiftNode(forX, ConstantNode.forInt(bits - 1)); + UnsignedRightShiftNode round = new UnsignedRightShiftNode(sign, ConstantNode.forInt(bits - log2)); + dividend = BinaryArithmeticNode.add(dividend, round); + } + RightShiftNode shift = new RightShiftNode(dividend, ConstantNode.forInt(log2)); + if (c < 0) { + return NegateNode.create(shift); + } + return shift; + } + return null; + } + @Override public void generate(NodeLIRBuilderTool gen) { gen.setResult(this, gen.getLIRGeneratorTool().getArithmetic().emitDiv(gen.operand(getX()), gen.operand(getY()), gen.state(this)));