< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignedRemNode.java
Print this page
@@ -58,16 +58,30 @@
long y = forY.asJavaConstant().asLong();
if (y == 0) {
return this; // this will trap, can not canonicalize
}
return ConstantNode.forIntegerStamp(stamp(), forX.asJavaConstant().asLong() % y);
- } else if (forY.isConstant()) {
- long c = forY.asJavaConstant().asLong();
- if (c == 1 || c == -1) {
+ } else if (forY.isConstant() && forX.stamp() instanceof IntegerStamp && forY.stamp() instanceof IntegerStamp) {
+ long constY = forY.asJavaConstant().asLong();
+ IntegerStamp xStamp = (IntegerStamp) forX.stamp();
+ IntegerStamp yStamp = (IntegerStamp) forY.stamp();
+ if (constY < 0 && constY != CodeUtil.minValue(yStamp.getBits())) {
+ return new SignedRemNode(forX, ConstantNode.forIntegerStamp(yStamp, -constY)).canonical(tool);
+ }
+
+ if (constY == 1) {
return ConstantNode.forIntegerStamp(stamp(), 0);
- } else if (c > 0 && CodeUtil.isPowerOf2(c) && forX.stamp() instanceof IntegerStamp && ((IntegerStamp) forX.stamp()).isPositive()) {
- return new AndNode(forX, ConstantNode.forIntegerStamp(stamp(), c - 1));
+ } else if (CodeUtil.isPowerOf2(constY)) {
+ if (xStamp.isPositive()) {
+ return new AndNode(forX, ConstantNode.forIntegerStamp(stamp(), constY - 1));
+ } else if (xStamp.isNegative()) {
+ return new NegateNode(new AndNode(new NegateNode(forX), ConstantNode.forIntegerStamp(stamp(), constY - 1)));
+ } else {
+ return new ConditionalNode(IntegerLessThanNode.create(forX, ConstantNode.forIntegerStamp(forX.stamp(), 0)),
+ new NegateNode(new AndNode(new NegateNode(forX), ConstantNode.forIntegerStamp(stamp(), constY - 1))),
+ new AndNode(forX, ConstantNode.forIntegerStamp(stamp(), constY - 1)));
+ }
}
}
return this;
}
< prev index next >