Skip to content

Commit a53195a

Browse files
committed
JDK-8384871 prototype
1 parent c0500ca commit a53195a

3 files changed

Lines changed: 95 additions & 3 deletions

File tree

src/hotspot/share/c1/c1_Canonicalizer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,8 @@ void Canonicalizer::do_If(If* x) {
724724
return;
725725
}
726726

727-
if (lt->is_constant() && rt->is_constant()) {
727+
// Fix (1)
728+
if (lt->is_constant() && rt->is_constant() && !x->substitutability_check()) {
728729
if (x->x()->as_Constant() != nullptr) {
729730
// pattern: If (lc cond rc) => simplify to: Goto
730731
BlockBegin* sux = x->x()->as_Constant()->compare(x->cond(), x->y(),

src/hotspot/share/c1/c1_Optimizer.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,8 @@ Value CE_Eliminator::make_ifop(Value x, Instruction::Condition cond, Value y, Va
289289
y = y->subst();
290290

291291
Constant* y_const = y->as_Constant();
292-
if (y_const != nullptr) {
292+
// Fix (2)
293+
if (!substitutability_check && y_const != nullptr) {
293294
IfOp* x_ifop = x->as_IfOp();
294295
if (x_ifop != nullptr) { // x is an ifop, y is a constant
295296
Constant* x_tval_const = x_ifop->tval()->subst()->as_Constant();
@@ -310,7 +311,8 @@ Value CE_Eliminator::make_ifop(Value x, Instruction::Condition cond, Value y, Va
310311
if (new_tval == new_fval) {
311312
return new_tval;
312313
} else {
313-
return new IfOp(x_ifop->x(), x_ifop_cond, x_ifop->y(), new_tval, new_fval, state_before, substitutability_check);
314+
// Fix (3)
315+
return new IfOp(x_ifop->x(), x_ifop_cond, x_ifop->y(), new_tval, new_fval, x_ifop->state_before(), x_ifop->substitutability_check());
314316
}
315317
}
316318
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright (c) 2026, Oracle and/or its affiliates. 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+
* @summary Test that C1's conditional folding preserves acmp substitutability.
27+
* @enablePreview
28+
* @library /test/lib
29+
* @run main ${test.main.class}
30+
* @run main/othervm -XX:TieredStopAtLevel=1 -Xbatch
31+
* -XX:CompileCommand=compileonly,${test.main.class}::test*
32+
* -XX:CompileCommand=inline,${test.main.class}::helper*
33+
* ${test.main.class}
34+
*/
35+
36+
package compiler.valhalla.inlinetypes;
37+
38+
import jdk.test.lib.Asserts;
39+
40+
public class TestC1AcmpCEE {
41+
private static final Integer CONSTANT = Integer.MAX_VALUE;
42+
private static final Integer CONSTANT_EQUAL = 2147483647;
43+
44+
// Helper to prevent javac from optimizing these shapes already
45+
public static int helper(boolean b) {
46+
if (b) {
47+
return 42;
48+
} else {
49+
return 0;
50+
}
51+
}
52+
53+
// Test for fix (1)
54+
public static int testDirectIntegerConstantCompareEqual() {
55+
if (CONSTANT == CONSTANT_EQUAL) {
56+
return 42;
57+
} else {
58+
return 0;
59+
}
60+
}
61+
62+
// Test for fix (2)
63+
public static int testDirectIntegerConstantCEEEqual() {
64+
return (CONSTANT == CONSTANT_EQUAL) ? 42 : 0;
65+
}
66+
67+
// Test for fix (3)
68+
public static int testNestedIfOp(Integer left, Integer right) {
69+
// After inlining helper, the code looks like this:
70+
//
71+
// b = IfOp(left == right ? true : false) // needs substitutability
72+
// result = IfOp(b == true ? 42 : 0)
73+
//
74+
// CEE collapses this into one conditional expression. The new IfOp
75+
// represents the original acmp and must keep its substitutability state.
76+
boolean b = (left == right);
77+
return helper(b);
78+
}
79+
80+
public static void main(String[] args) {
81+
for (int i = 0; i < 20_000; i++) {
82+
Asserts.assertEQ(42, testDirectIntegerConstantCompareEqual());
83+
Asserts.assertEQ(42, testDirectIntegerConstantCEEEqual());
84+
Asserts.assertEQ(42, testNestedIfOp(Integer.MAX_VALUE, Integer.MAX_VALUE));
85+
Asserts.assertEQ(0, testNestedIfOp(Integer.MAX_VALUE, Integer.MAX_VALUE + 1));
86+
}
87+
}
88+
}
89+

0 commit comments

Comments
 (0)