Skip to content

Commit 2c0d9a7

Browse files
galderzrwestrel
authored andcommitted
8373396: Min and Max Ideal missing AddNode::Ideal optimisations
Reviewed-by: epeter, roland
1 parent 2ba423d commit 2c0d9a7

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

src/hotspot/share/opto/addnode.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,10 @@ static ConstAddOperands as_add_with_constant(Node* n) {
13281328
}
13291329

13301330
Node* MaxNode::IdealI(PhaseGVN* phase, bool can_reshape) {
1331+
Node* n = AddNode::Ideal(phase, can_reshape);
1332+
if (n != nullptr) {
1333+
return n;
1334+
}
13311335
int opcode = Opcode();
13321336
assert(opcode == Op_MinI || opcode == Op_MaxI, "Unexpected opcode");
13331337
// Try to transform the following pattern, in any of its four possible
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
* Copyright (c) 2025 IBM Corporation. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8373396
27+
* @summary Verify that min/max add ideal optimizations get applied correctly
28+
* @modules java.base/jdk.internal.misc
29+
* @library /test/lib /
30+
* @run driver ${test.main.class}
31+
*/
32+
33+
package compiler.igvn;
34+
35+
import compiler.lib.compile_framework.CompileFramework;
36+
import compiler.lib.template_framework.Template;
37+
import compiler.lib.template_framework.TemplateToken;
38+
import compiler.lib.template_framework.library.CodeGenerationDataNameType;
39+
import compiler.lib.template_framework.library.PrimitiveType;
40+
import compiler.lib.template_framework.library.TestFrameworkClass;
41+
42+
import java.util.Collections;
43+
import java.util.List;
44+
import java.util.stream.Stream;
45+
46+
import static compiler.lib.template_framework.Template.let;
47+
import static compiler.lib.template_framework.Template.scope;
48+
49+
public class TestMinMaxIdeal {
50+
public static void main(String[] args) {
51+
// Create a new CompileFramework instance.
52+
CompileFramework comp = new CompileFramework();
53+
54+
// Add a java source file.
55+
comp.addJavaSourceCode("compiler.igvn.templated.MinMaxIdeal", generate(comp));
56+
57+
// Compile the source file.
58+
comp.compile();
59+
60+
comp.invoke("compiler.igvn.templated.MinMaxIdeal", "main", new Object[] {new String[] {}});
61+
}
62+
63+
private static String generate(CompileFramework comp) {
64+
// Create a list to collect all tests.
65+
List<TemplateToken> testTemplateTokens = Stream.of(Op.values())
66+
.map(op -> new TestGenerator(op).generate())
67+
.toList();
68+
69+
// Create the test class, which runs all testTemplateTokens.
70+
return TestFrameworkClass.render(
71+
// package and class name.
72+
"compiler.igvn.templated", "MinMaxIdeal",
73+
// List of imports.
74+
Collections.emptySet(),
75+
// classpath, so the Test VM has access to the compiled class files.
76+
comp.getEscapedClassPathOfCompiledClasses(),
77+
// The list of tests.
78+
testTemplateTokens);
79+
}
80+
81+
enum Op {
82+
MIN_I("min", CodeGenerationDataNameType.ints()),
83+
MAX_I("max", CodeGenerationDataNameType.ints()),
84+
MIN_L("min", CodeGenerationDataNameType.longs()),
85+
MAX_L("max", CodeGenerationDataNameType.longs());
86+
87+
final String functionName;
88+
final PrimitiveType type;
89+
90+
Op(String functionName, PrimitiveType type) {
91+
this.functionName = functionName;
92+
this.type = type;
93+
}
94+
}
95+
96+
record TestGenerator(Op op) {
97+
TemplateToken generate() {
98+
var template = Template.make(() -> scope(
99+
let("boxedTypeName", op.type.boxedTypeName()),
100+
let("op", op.name()),
101+
let("type", op.type.name()),
102+
let("functionName", op.functionName),
103+
"""
104+
@Test
105+
@IR(counts = {IRNode.#op, "= 1"},
106+
phase = CompilePhase.BEFORE_MACRO_EXPANSION)
107+
@Arguments(values = {Argument.NUMBER_42, Argument.NUMBER_42})
108+
public #type test_commute_#op(#type a, #type b) {
109+
return #boxedTypeName.#functionName(a, b) + #boxedTypeName.#functionName(b, a);
110+
}
111+
112+
@Test
113+
@IR(counts = {IRNode.#op, "= 1"},
114+
phase = CompilePhase.BEFORE_MACRO_EXPANSION)
115+
@Arguments(values = {Argument.NUMBER_42})
116+
public #type test_flatten_#op(#type a) {
117+
return #boxedTypeName.#functionName(#boxedTypeName.#functionName(a, 1), 2);
118+
}
119+
120+
@Test
121+
@IR(counts = {IRNode.#op, "= 2"},
122+
phase = CompilePhase.BEFORE_MACRO_EXPANSION)
123+
@Arguments(values = {Argument.NUMBER_42, Argument.NUMBER_42})
124+
public #type test_push_constant_left_#op(#type a, #type b) {
125+
return #boxedTypeName.#functionName(#boxedTypeName.#functionName(a, 1), b) + #boxedTypeName.#functionName(b, a);
126+
}
127+
128+
@Test
129+
@IR(counts = {IRNode.#op, "= 2"},
130+
phase = CompilePhase.BEFORE_MACRO_EXPANSION)
131+
@Arguments(values = {Argument.NUMBER_42, Argument.NUMBER_42})
132+
public #type test_push_constant_right_#op(#type a, #type b) {
133+
return #boxedTypeName.#functionName(a, #boxedTypeName.#functionName(b, 1)) + #boxedTypeName.#functionName(b, a);
134+
}
135+
"""
136+
));
137+
return template.asToken();
138+
}
139+
}
140+
}

0 commit comments

Comments
 (0)