RFR: 8347555: [REDO] C2: implement optimization for series of Add of unique value [v19]

Roland Westrelin roland at openjdk.org
Thu Oct 2 08:06:08 UTC 2025


On Wed, 1 Oct 2025 04:48:35 GMT, Kangcheng Xu <kxu at openjdk.org> wrote:

>> [JDK-8347555](https://bugs.openjdk.org/browse/JDK-8347555) is a redo of [JDK-8325495](https://bugs.openjdk.org/browse/JDK-8325495) was [first merged](https://git.openjdk.org/jdk/pull/20754) then backed out due to a regression. This patch redos the feature and fixes the bit shift overflow problem. For more information please refer to the previous PR.
>> 
>> When constanlizing multiplications (possibly in forms on `lshifts`), the multiplier is upgraded to long and then later narrowed to int if needed. However, when a `lshift` operand is exactly `32`, overflowing an int, using long has an unexpected result. (i.e., `(1 << 32) = 1` and `(int) (1L << 32) = 0`)
>> 
>> The following was implemented to address this issue.
>> 
>> if (UseNewCode2) {
>>     *multiplier = bt == T_INT
>>         ? (jlong) (1 << con->get_int()) // loss of precision is expected for int as it overflows
>>         : ((jlong) 1) << con->get_int();
>> } else {
>>     *multiplier = ((jlong) 1 << con->get_int());
>> }
>> 
>> 
>> Two new bitshift overflow tests were added.
>
> Kangcheng Xu has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 69 commits:
> 
>  - Merge remote-tracking branch 'origin/master' into arithmetic-canonicalization
>  - update naming and comments
>  - Merge branch 'openjdk:master' into arithmetic-canonicalization
>  - Merge remote-tracking branch 'origin/master' into arithmetic-canonicalization
>  - Allow swapping LHS/RHS in case not matched
>  - Merge branch 'refs/heads/master' into arithmetic-canonicalization
>  - improve comment readability and struct helper functions
>  - remove asserts, add more documentation
>  - fix typo: lhs->rhs
>  - update comments
>  - ... and 59 more: https://git.openjdk.org/jdk/compare/0366d882...ce23d393

src/hotspot/share/opto/addnode.cpp line 555:

> 553: 
> 554:     // Pattern (1)
> 555:     if (lhs.valid && rhs.valid && lhs.variable == rhs.variable) {

Would it make sense to add a method to `Multiplication`, let's say `add`. The 3 `if`s here would then be replaced by:

Multiplication res = lhs.add(rhs);
if (res.valid()) {
  return res;
}
return find_simple_addition_pattern(n, bt);

and the logic from the 3 ifs would be moved to `Multiplication::add`.
What do you think?

src/hotspot/share/opto/addnode.hpp line 46:

> 44:   virtual uint hash() const;
> 45: 
> 46:   struct Multiplication {

Is there a benefit to this being a `struct` instead of a `class`?

src/hotspot/share/opto/addnode.hpp line 47:

> 45: 
> 46:   struct Multiplication {
> 47:     bool valid = false;

field names usually start with a `_` so `bool _valid`

src/hotspot/share/opto/addnode.hpp line 60:

> 58:   };
> 59: 
> 60:   static Multiplication find_collapsible_addition_patterns(const Node* a, const Node* pattern, BasicType bt);

Shouldn't these methods be member methods of `Multiplication`

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

PR Review Comment: https://git.openjdk.org/jdk/pull/23506#discussion_r2397605619
PR Review Comment: https://git.openjdk.org/jdk/pull/23506#discussion_r2397579068
PR Review Comment: https://git.openjdk.org/jdk/pull/23506#discussion_r2397581099
PR Review Comment: https://git.openjdk.org/jdk/pull/23506#discussion_r2397584858


More information about the hotspot-compiler-dev mailing list