Skip to content

Commit cdada02

Browse files
committed
[GR-60865] Mask constant shift amount for reassociation
PullRequest: graal/19740
2 parents a10f5f3 + 5bc71de commit cdada02

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/calc/LeftShiftNode.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,7 @@
3939
import jdk.graal.compiler.nodes.ValueNode;
4040
import jdk.graal.compiler.nodes.spi.CanonicalizerTool;
4141
import jdk.graal.compiler.nodes.spi.NodeLIRBuilderTool;
42+
import jdk.vm.ci.code.CodeUtil;
4243
import jdk.vm.ci.meta.Constant;
4344
import jdk.vm.ci.meta.JavaKind;
4445
import jdk.vm.ci.meta.PrimitiveConstant;
@@ -109,13 +110,21 @@ public MulNode getEquivalentMulNode() {
109110
if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) {
110111
IntegerStamp xStamp = (IntegerStamp) getX().stamp(NodeView.DEFAULT);
111112
if (xStamp.getBits() == selfStamp.getBits()) {
112-
long i = ((PrimitiveConstant) c).asLong();
113+
long shiftAmount = ((PrimitiveConstant) c).asLong();
113114
/*
114-
* If i == 63, this will give Long.MIN_VALUE, which is negative but still
115-
* correct as the multiplier. We have to do a shift here, computing this as
116-
* (long) Math.pow(2, 63) would round to the wrong value.
115+
* The shift below is done in long arithmetic, but if the underlying values are
116+
* ints (or smaller), we must shift according to int semantics. So mask
117+
* accordingly.
117118
*/
118-
long multiplier = 1L << i;
119+
if (selfStamp.getBits() <= Integer.SIZE) {
120+
shiftAmount &= CodeUtil.mask(CodeUtil.log2(Integer.SIZE));
121+
}
122+
/*
123+
* If shiftAmount == 63, this will give Long.MIN_VALUE, which is negative but
124+
* still correct as the multiplier. We have to do a shift here, computing this
125+
* as (long) Math.pow(2, 63) would round to the wrong value.
126+
*/
127+
long multiplier = 1L << shiftAmount;
119128
return new MulNode(getX(), ConstantNode.forIntegerStamp(xStamp, multiplier));
120129
}
121130
}

0 commit comments

Comments
 (0)