Skip to content

8373396: Min and Max Ideal missing AddNode::Ideal optimisations#28770

Closed
galderz wants to merge 11 commits intoopenjdk:masterfrom
galderz:topic.commute-et-al
Closed

8373396: Min and Max Ideal missing AddNode::Ideal optimisations#28770
galderz wants to merge 11 commits intoopenjdk:masterfrom
galderz:topic.commute-et-al

Conversation

@galderz
Copy link
Copy Markdown
Contributor

@galderz galderz commented Dec 11, 2025

MaxI and MinI are missing AddNode::Ideal optimizations. These optimizations include commutation, flattening, pushing constants...etc. The PR changes MaxINode::Ideal and MinINode::Ideal to call AddNode::Ideal. Long versions already call AddNode::Ideal so nothing to change there.

The PR also includes a template framework generated test (cc @eme64) that verifies that all of AddNode::Ideal optimizations now apply correctly for min/max for longs and ints. Long tests have been added to validate that both ints and longs produce the same results.

Fixing this issue indirectly fixes compiler/codegen/TestBooleanVect.java when run with -XX:VerifyIterativeGVN=1110, which was failing due to min not having one of those optimisations. However, this PR does not make changes to PhaseIterGVN::verify_Identity_for because there are additional failures observed with min/max for integers in JDK-8373134. Therefore, changes there will in the PR for JDK-8373134 instead.

Update 15.12.25: PhaseIterGVN::verify_Ideal_for exceptions for MinI/MaxI are still needed.

If you look at PhaseIterGVN::verify_Ideal_for, it contains. This looks like it could be removed in this PR as it looks like they were quite likely disabled due to the issue here. However, it's unclear what test was failing here (@eme64 ?):

    // MinINode::Ideal
    // Did not investigate, but there are some patterns that might
    // need more notification.
    case Op_MinI:
    case Op_MaxI: // preemptively removed it as well.
      return false;

I've run tier1-3 tests on linux/x64 and they passed.


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8373396: Min and Max Ideal missing AddNode::Ideal optimisations (Enhancement - P4)

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/28770/head:pull/28770
$ git checkout pull/28770

Update a local copy of the PR:
$ git checkout pull/28770
$ git pull https://git.openjdk.org/jdk.git pull/28770/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 28770

View PR using the GUI difftool:
$ git pr show -t 28770

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/28770.diff

Using Webrev

Link to Webrev Comment

* Optimizations include commutation, flattening, pushing constants...etc.
* Added template framework generated test for all optimizations
that AddNode::Ideal covers.
* Test for ints and longs, both of which call AddNode::Ideal.
@bridgekeeper
Copy link
Copy Markdown

bridgekeeper bot commented Dec 11, 2025

👋 Welcome back galder! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link
Copy Markdown

openjdk bot commented Dec 11, 2025

@galderz This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8373396: Min and Max Ideal missing AddNode::Ideal optimisations

Reviewed-by: epeter, roland

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 131 new commits pushed to the master branch:

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@eme64, @rwestrel) but any other Committer may sponsor as well.

➡️ To flag this PR as ready for integration with the above commit message, type /integrate in a new comment. (Afterwards, your sponsor types /sponsor in a new comment to perform the integration).

@openjdk openjdk bot added the hotspot-compiler hotspot-compiler-dev@openjdk.org label Dec 11, 2025
@openjdk
Copy link
Copy Markdown

openjdk bot commented Dec 11, 2025

@galderz The following label will be automatically applied to this pull request:

  • hotspot-compiler

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the rfr Pull request is ready for review label Dec 11, 2025
@mlbridge
Copy link
Copy Markdown

mlbridge bot commented Dec 11, 2025

Webrevs


// Ideal transformations for MaxINode
Node* MaxINode::Ideal(PhaseGVN* phase, bool can_reshape) {
Node* n = AddNode::Ideal(phase, can_reshape);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not move this into MaxNode::IdealI?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the call below return IdealI(phase, can_reshape); already looks like it wants to handle all the superclass optimiazations. So it should go in there.

Copy link
Copy Markdown
Contributor

@eme64 eme64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@galderz Nice, this looks like a good use-case of the template framework, it reduces the test size!

It still feels a bit boiler-plate-y ... but it is a step in the right direction for sure ☺️


// Ideal transformations for MaxINode
Node* MaxINode::Ideal(PhaseGVN* phase, bool can_reshape) {
Node* n = AddNode::Ideal(phase, can_reshape);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the call below return IdealI(phase, can_reshape); already looks like it wants to handle all the superclass optimiazations. So it should go in there.

* @summary Verify that min/max add ideal optimizations get applied correctly
* @modules java.base/jdk.internal.misc
* @library /test/lib /
* @run driver compiler.c2.irTests.TestMinMaxIdeal
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @run driver compiler.c2.irTests.TestMinMaxIdeal
* @run driver ${test.main.class}

Also: please don't put any new tests in irTests. Rather put it in a directory based on the topic.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did think about that but then I saw TestMinMaxIdentities was on the package so thought of adding it next to it. What about putting it in compiler.intrinsics.math instead?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it belongs more under idealization. So either a gvn or igvn directory.

Comment on lines +54 to +56
String templatedPackage ="compiler.c2.templated";
String templatedClassName ="MinMaxIdeal";
String templatedFQN = "%s.%s".formatted(templatedPackage, templatedClassName);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks a bit convoluted. Why not just use the final string?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure exactly what you mean. For addJavaSourceCode I need the combined FQN and for TestFrameworkClass.render I need the classname and package separated.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is just a nit, I leave it to you. I'm also fine taking it as is :)

Comment on lines +71 to +74
testTemplateTokens.add(new TestGenerator(Op.MIN_I).generate());
testTemplateTokens.add(new TestGenerator(Op.MAX_I).generate());
testTemplateTokens.add(new TestGenerator(Op.MIN_L).generate());
testTemplateTokens.add(new TestGenerator(Op.MAX_L).generate());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use Op.values() -> List, then iterate over that?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, better indeed. It avoids issues adding an enum value and forgetting to add it (I already did that lol)

@galderz
Copy link
Copy Markdown
Contributor Author

galderz commented Dec 12, 2025

@TobiHartmann Thanks for the review!

@eme64 Thanks also for the review. Can you please also clarify what I said about potentially changing PhaseIterGVN::verify_Ideal_for in the description?

@eme64
Copy link
Copy Markdown
Contributor

eme64 commented Dec 12, 2025

@TobiHartmann Thanks for the review!

@eme64 Thanks also for the review. Can you please also clarify what I said about potentially changing PhaseIterGVN::verify_Ideal_for in the description?

I don't remember. Try enabling the verification, and see if you find any test that fails. If not: great, maybe you fixed it! If it still fails, it would be nice if you added more info, but not neccessary.

I don't remember because there were eventually too many cases and I stopped reporting which had failed.

@galderz
Copy link
Copy Markdown
Contributor Author

galderz commented Dec 15, 2025

I don't remember. Try enabling the verification, and see if you find any test that fails. If not: great, maybe you fixed it! If it still fails, it would be nice if you added more info, but not neccessary.

It still fails with other optimisation missing, so I will revert that the commit that uncommented that:

----------messages:(7/385)----------
command: main -Xcomp -XX:VerifyIterativeGVN=1111 compiler.c2.TestVerifyIterativeGVN
reason: User specified action: run main/othervm/timeout=300 -Xcomp -XX:VerifyIterativeGVN=1111 compiler.c2.TestVerifyIterativeGVN 
started: Mon Dec 15 09:07:06.937 CET 2025
Mode: othervm [/othervm specified]
Process id: 133090
finished: Mon Dec 15 09:07:45.303 CET 2025
elapsed time (seconds): 38.366
----------configuration:(0/0)----------
----------System.out:(32/1990)----------

Missed Ideal optimization (can_reshape=false):
The node was reshaped by Ideal.
The result after Ideal:
dist dump
---------------------------------------------
   1  1612  AddI  === _ 1880 668  [[ 1258 ]]  !orig=[3471] !jvms: DirectMethodHandle::makePreparedLambdaForm @ bci:612 (line 293)
   1  1254  CastII  === 1519 1606  [[ 881 1258 1879 1607 870 2028 ]]  #int:0..maxint-1, widen: 3 !orig=[5228],[3463] !jvms: DirectMethodHandle::makePreparedLambdaForm @ bci:612 (line 293)
   0  1258  MinI  === _ 1254 1612  [[ 871 ]]  !jvms: DirectMethodHandle::makePreparedLambdaForm @ bci:612 (line 293)

@galderz
Copy link
Copy Markdown
Contributor Author

galderz commented Dec 15, 2025

I've reverted the PhaseIterGVN::verify_Ideal_for changes suggested in the description. Tier1-3 testing looks good otherwise.

@TobiHartmann @eme64 Could you please review it once more? Thanks!

Copy link
Copy Markdown
Contributor

@eme64 eme64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good now, except that little nit below.

We can run some internal testing once a second reviewer has had a look :)

Comment on lines +99 to +101
let("irNodeName", op.name()),
let("boxedTypeName", op.type.boxedTypeName()),
let("op", op.name()),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: you are repeating the same value op.name() with two hashtags op and irNodeName. Is that intentional?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I'll get it fixed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just pushed a fix

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Dec 16, 2025
@openjdk openjdk bot removed the ready Pull request is ready to be integrated label Dec 16, 2025
Copy link
Copy Markdown
Contributor

@eme64 eme64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, looks cleaner now :)

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Dec 16, 2025
Copy link
Copy Markdown
Contributor

@rwestrel rwestrel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@galderz
Copy link
Copy Markdown
Contributor Author

galderz commented Dec 16, 2025

@eme64 Roland provided the 2nd review so you can start your internal testing.

@eme64
Copy link
Copy Markdown
Contributor

eme64 commented Dec 16, 2025

Testing launched 🚀

@eme64
Copy link
Copy Markdown
Contributor

eme64 commented Dec 18, 2025

Testing passed, ship it 🚢 !

@galderz
Copy link
Copy Markdown
Contributor Author

galderz commented Dec 18, 2025

/integrate

@openjdk openjdk bot added the sponsor Pull request is ready to be sponsored label Dec 18, 2025
@openjdk
Copy link
Copy Markdown

openjdk bot commented Dec 18, 2025

@galderz
Your change (at version b1ab81b) is now ready to be sponsored by a Committer.

@rwestrel
Copy link
Copy Markdown
Contributor

/sponsor

@openjdk
Copy link
Copy Markdown

openjdk bot commented Dec 18, 2025

Going to push as commit 2c0d9a7.
Since your change was applied there have been 131 commits pushed to the master branch:

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label Dec 18, 2025
@openjdk openjdk bot closed this Dec 18, 2025
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review sponsor Pull request is ready to be sponsored labels Dec 18, 2025
@openjdk
Copy link
Copy Markdown

openjdk bot commented Dec 18, 2025

@rwestrel @galderz Pushed as commit 2c0d9a7.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

@galderz
Copy link
Copy Markdown
Contributor Author

galderz commented Dec 18, 2025

Thanks @eme64 and @rwestrel for the reviews!

@galderz galderz deleted the topic.commute-et-al branch December 18, 2025 11:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hotspot-compiler hotspot-compiler-dev@openjdk.org integrated Pull request has been integrated

Development

Successfully merging this pull request may close these issues.

4 participants