diff --git a/src/hotspot/share/opto/cfgnode.cpp b/src/hotspot/share/opto/cfgnode.cpp index c6505effc77..42f5e488642 100644 --- a/src/hotspot/share/opto/cfgnode.cpp +++ b/src/hotspot/share/opto/cfgnode.cpp @@ -1476,6 +1476,10 @@ Node* PhiNode::Identity(PhaseGVN* phase) { if (uin != nullptr) { return uin; } + uin = unique_input_recursive(phase); + if (uin != nullptr) { + return uin; + } int true_path = is_diamond_phi(); // Delay CMove'ing identity if Ideal has not had the chance to handle unsafe cases, yet. @@ -1575,6 +1579,39 @@ Node* PhiNode::unique_input(PhaseValues* phase, bool uncast) { return nullptr; } +// Find the unique input, try to look recursively through input Phis +Node* PhiNode::unique_input_recursive(PhaseGVN* phase) { + if (!phase->is_IterGVN()) { + return nullptr; + } + + ResourceMark rm; + Node* unique = nullptr; + Unique_Node_List visited; + visited.push(this); + + for (uint visited_idx = 0; visited_idx < visited.size(); visited_idx++) { + Node* current = visited.at(visited_idx); + for (uint i = 1; i < current->req(); i++) { + Node* phi_in = current->in(i); + if (phi_in == nullptr) { + continue; + } + + if (phi_in->is_Phi()) { + visited.push(phi_in); + } else { + if (unique == nullptr) { + unique = phi_in; + } else if (unique != phi_in) { + return nullptr; + } + } + } + } + return unique; +} + //------------------------------is_x2logic------------------------------------- // Check for simple convert-to-boolean pattern // If:(C Bool) Region:(IfF IfT) Phi:(Region 0 1) diff --git a/src/hotspot/share/opto/cfgnode.hpp b/src/hotspot/share/opto/cfgnode.hpp index 73aa2595291..988283ad9ea 100644 --- a/src/hotspot/share/opto/cfgnode.hpp +++ b/src/hotspot/share/opto/cfgnode.hpp @@ -232,6 +232,7 @@ class PhiNode : public TypeNode { } return uin; } + Node* unique_input_recursive(PhaseGVN* phase); // Check for a simple dead loop. enum LoopSafety { Safe = 0, Unsafe, UnsafeLoop }; diff --git a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java index 45f30bf1f43..d63b94d8d45 100644 --- a/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java +++ b/test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java @@ -4158,13 +4158,14 @@ public void test150_verifier() { Asserts.assertEquals(test150(), testValue2.hash()); } -// TODO 8336003 This triggers # assert(false) failed: Should have been buffered -/* - // Same as test150 but with val not being allocated in the scope of the method + // Same as test150 but with a real loop and val not being allocated in the scope of the method @Test + // Dynamic call does not null check the receiver, so it cannot be strength reduced to a static + // call without an explicit null check @IR(failOn = {compiler.lib.ir_framework.IRNode.DYNAMIC_CALL_OF_METHOD, "MyValue2::hash"}, counts = {compiler.lib.ir_framework.IRNode.STATIC_CALL_OF_METHOD, "MyValue2::hash", "= 1"}) public long test151(MyValue2 val) { + val = Objects.requireNonNull(val); MyAbstract receiver = MyValue1.createWithFieldsInline(rI, rL); for (int i = 0; i < 100; i++) { @@ -4182,7 +4183,6 @@ public long test151(MyValue2 val) { public void test151_verifier() { Asserts.assertEquals(test151(testValue2), testValue2.hash()); } -*/ static interface MyInterface2 { public int val();