RFR: 8288564: C2: LShiftLNode::Ideal produces wrong result after JDK-8278114 [v2]

Christian Hagedorn chagedorn at openjdk.org
Fri Jun 17 08:46:39 UTC 2022


> [JDK-8278114](https://bugs.openjdk.org/browse/JDK-8278114) added the following transformation for integer and long left shifts:
> 
>  "(x + x) << c0" into "x << (c0 + 1)"
> 
> However, in the long shift case, this transformation is not correct if `c0` is 63:
> 
> 
> (x + x) << 63 = 2x << 63
> 
> while
> 
>  (x + x) << 63 --transform--> x << 64 = x << 0 = x
> 
> which is not the same. For example, if `x = 1`:
> 
> 2x << 63 = 2 << 63 = 0 != 1
> 
> This optimization does not account for the fact that `x << 64` is the same as `x << 0 = x`. According to the [Java spec, chapter 15.19](https://docs.oracle.com/javase/specs/jls/se18/html/jls-15.html#jls-15.19), we only consider the six lowest-order bits of the right-hand operand (i.e. `"right-hand operand" & 0b111111`). Therefore, `x << 64` is the same as `x << 0` (`64 = 0b10000000 & 0b0111111 = 0`).
> 
> Integer shifts are not affected because we do not apply this transformation if `c0 >= 16`:
> 
> https://urldefense.com/v3/__https://github.com/openjdk/jdk19/blob/729164f53499f146579a48ba1b466c687802f330/src/hotspot/share/opto/mulnode.cpp*L810-L817__;Iw!!ACWV5N9M2RV99hQ!ICZkZ9LN5SiFfPdb_0uKzKgdF8PS_wHwhOdRPnzCAFo-FXzQEph7m8vlhGz1gtm7OEa3axFS6CrSBBGERFQnKvctc9UqfSPlyQ$ 
> 
> The fix I propose is to not apply this optimization for long left shifts if `c0 == 63`. I've added an additional sanity assertion for integer left shifts just in case this optimization is moved at some point and ending up outside the check for `con < 16`.
> 
> Thanks,
> Christian

Christian Hagedorn has updated the pull request incrementally with two additional commits since the last revision:

 - typo
 - change assert to comment

-------------

Changes:
  - all: https://git.openjdk.org/jdk19/pull/29/files
  - new: https://git.openjdk.org/jdk19/pull/29/files/37040f94..45b1e994

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk19&pr=29&range=01
 - incr: https://webrevs.openjdk.org/?repo=jdk19&pr=29&range=00-01

  Stats: 2 lines in 1 file changed: 1 ins; 0 del; 1 mod
  Patch: https://git.openjdk.org/jdk19/pull/29.diff
  Fetch: git fetch https://git.openjdk.org/jdk19 pull/29/head:pull/29

PR: https://git.openjdk.org/jdk19/pull/29


More information about the hotspot-compiler-dev mailing list