-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8371716: C2: Phi node fails Value()'s verification when speculative types clash #28331
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 2 commits
818895e
7ac02cb
e9f3ac9
42fedf0
006b1e5
7a092da
1c28403
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -1351,6 +1351,82 @@ const Type* PhiNode::Value(PhaseGVN* phase) const { | |||||
| } | ||||||
| #endif //ASSERT | ||||||
|
|
||||||
|
|
||||||
| // In rare cases, `_type` and `t` have incompatible opinion on speculative type, resulting into a too small intersection | ||||||
| // (such as AnyNull), which is removed in cleanup_speculative. From that `ft` has empty speculative type. After the end | ||||||
| // of the current `Value` call, `ft` (that is returned) is becoming `_type`. If verification happens then, `t` would be the | ||||||
| // same (union of input types), but the new `_type` has now no speculative type, the result of `t->filter_speculative(_type)` | ||||||
| // has the speculative type of `t` (if it's not removed because e.g. the resulting type is exact and non null) and not empty | ||||||
| // (like the previously returned type). In such a case, doing the filtering one time more allows to reach a fixpoint. | ||||||
|
||||||
| if (ft->speculative() == nullptr && t->speculative() != nullptr) { | ||||||
| const Type* first_ft = ft; | ||||||
| ft = t->filter_speculative(first_ft); | ||||||
| #ifdef ASSERT | ||||||
|
||||||
| // The following logic has been moved into TypeOopPtr::filter. | ||||||
|
||||||
| const Type* jt = t->join_speculative(first_ft); | ||||||
| if (jt->empty()) { // Emptied out??? | ||||||
|
||||||
| if (jt->empty()) { // Emptied out??? | |
| if (jt->empty()) { |
Comment seems redundant.
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Formatting looks a bit funny here.
marc-chevalier marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,84 @@ | ||||||
| /* | ||||||
| * Copyright (c) 2025, Red Hat, Inc. | ||||||
| * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. | ||||||
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||||||
| * | ||||||
| * This code is free software; you can redistribute it and/or modify it | ||||||
| * under the terms of the GNU General Public License version 2 only, as | ||||||
| * published by the Free Software Foundation. | ||||||
| * | ||||||
| * This code is distributed in the hope that it will be useful, but WITHOUT | ||||||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||||
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||||||
| * version 2 for more details (a copy is included in the LICENSE file that | ||||||
| * accompanied this code). | ||||||
| * | ||||||
| * You should have received a copy of the GNU General Public License version | ||||||
| * 2 along with this work; if not, write to the Free Software Foundation, | ||||||
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||||||
| * | ||||||
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||||||
| * or visit www.oracle.com if you need additional information or have any | ||||||
| * questions. | ||||||
| */ | ||||||
|
|
||||||
| /** | ||||||
| * @test | ||||||
| * @bug 8371716 | ||||||
| * @summary Ranges can be proven to be disjoint but not orderable (thanks to unsigned range) | ||||||
| * Comparing such values in such range with != should always be true. | ||||||
| * @run main/othervm -XX:-TieredCompilation | ||||||
| * -XX:-UseOnStackReplacement | ||||||
| * -XX:-BackgroundCompilation | ||||||
| * -XX:CompileOnly=compiler.igvn.ClashingSpeculativeTypePhiNode::test1 | ||||||
| * -XX:CompileCommand=quiet | ||||||
| * -XX:TypeProfileLevel=222 | ||||||
| * -XX:+AlwaysIncrementalInline | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
GitHub Actions is giving us this: Probably this would help: |
||||||
| * -XX:VerifyIterativeGVN=10 | ||||||
| * -XX:CompileCommand=dontinline,compiler.igvn.ClashingSpeculativeTypePhiNode::notInlined1 | ||||||
| * compiler.igvn.ClashingSpeculativeTypePhiNode | ||||||
| * | ||||||
| * @run main compiler.igvn.ClashingSpeculativeTypePhiNode | ||||||
marc-chevalier marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| */ | ||||||
|
|
||||||
| package compiler.igvn; | ||||||
|
|
||||||
| public class ClashingSpeculativeTypePhiNode { | ||||||
| public static void main(String[] args) { | ||||||
| for (int i = 0; i < 20_000; i++) { | ||||||
| test1(false); | ||||||
| inlined1(true, true); | ||||||
| inlined2(false); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| private static Object test1(boolean flag1) { | ||||||
| return inlined1(flag1, false); | ||||||
| } | ||||||
|
|
||||||
| private static Object inlined1(boolean flag1, boolean flag2) { | ||||||
| if (flag1) { | ||||||
| return inlined2(flag2); // C1 | ||||||
| } | ||||||
| return null; | ||||||
| } | ||||||
|
|
||||||
| private static Object inlined2(boolean flag2) { | ||||||
| if (flag2) { | ||||||
| return new C1(); | ||||||
| } | ||||||
| return notInlined1(); // C2 | ||||||
| } | ||||||
|
|
||||||
| private static Object notInlined1() { | ||||||
| return new C2(); | ||||||
| } | ||||||
|
|
||||||
| static class C1 { | ||||||
|
|
||||||
| } | ||||||
|
|
||||||
| static class C2 { | ||||||
|
|
||||||
| } | ||||||
| } | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"becoming" is a bit ambiguous here, I first thought it meant
ft = _type, then realized one could also read it as_type = ft. Maybe you have an even better way to express it.