|
1 | 1 | /* |
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. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | 4 | * |
5 | 5 | * This code is free software; you can redistribute it and/or modify it |
|
39 | 39 | import jdk.graal.compiler.nodes.ValueNode; |
40 | 40 | import jdk.graal.compiler.nodes.spi.CanonicalizerTool; |
41 | 41 | import jdk.graal.compiler.nodes.spi.NodeLIRBuilderTool; |
| 42 | +import jdk.vm.ci.code.CodeUtil; |
42 | 43 | import jdk.vm.ci.meta.Constant; |
43 | 44 | import jdk.vm.ci.meta.JavaKind; |
44 | 45 | import jdk.vm.ci.meta.PrimitiveConstant; |
@@ -109,13 +110,21 @@ public MulNode getEquivalentMulNode() { |
109 | 110 | if (c instanceof PrimitiveConstant && ((PrimitiveConstant) c).getJavaKind().isNumericInteger()) { |
110 | 111 | IntegerStamp xStamp = (IntegerStamp) getX().stamp(NodeView.DEFAULT); |
111 | 112 | if (xStamp.getBits() == selfStamp.getBits()) { |
112 | | - long i = ((PrimitiveConstant) c).asLong(); |
| 113 | + long shiftAmount = ((PrimitiveConstant) c).asLong(); |
113 | 114 | /* |
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. |
117 | 118 | */ |
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; |
119 | 128 | return new MulNode(getX(), ConstantNode.forIntegerStamp(xStamp, multiplier)); |
120 | 129 | } |
121 | 130 | } |
|
0 commit comments