diff --git a/src/hotspot/share/opto/loopnode.hpp b/src/hotspot/share/opto/loopnode.hpp index fc4f58739a5..986cfdaa3f1 100644 --- a/src/hotspot/share/opto/loopnode.hpp +++ b/src/hotspot/share/opto/loopnode.hpp @@ -1960,7 +1960,7 @@ public: bool can_move_to_inner_loop(Node* n, LoopNode* n_loop, Node* x); - void pin_nodes_dependent_on(Node* ctrl); + void pin_nodes_dependent_on(Node* ctrl, bool old_iff_is_rangecheck); Node* ensure_node_and_inputs_are_above_pre_end(CountedLoopEndNode* pre_end, Node* node); diff --git a/src/hotspot/share/opto/split_if.cpp b/src/hotspot/share/opto/split_if.cpp index 0b5cbc5d60b..bf43a7506f0 100644 --- a/src/hotspot/share/opto/split_if.cpp +++ b/src/hotspot/share/opto/split_if.cpp @@ -29,6 +29,7 @@ #include "opto/movenode.hpp" #include "opto/node.hpp" #include "opto/opaquenode.hpp" +#include "opto/opcodes.hpp" #include "opto/predicates.hpp" //------------------------------split_thru_region------------------------------ @@ -719,8 +720,8 @@ void PhaseIdealLoop::do_split_if(Node* iff, RegionNode** new_false_region, Regio // Control is updated here to a region, which is not a test, so any node that // depends_only_on_test must be pinned - pin_nodes_dependent_on(new_true); - pin_nodes_dependent_on(new_false); + pin_nodes_dependent_on(new_true, iff->Opcode() == Op_RangeCheck); + pin_nodes_dependent_on(new_false, iff->Opcode() == Op_RangeCheck); if (new_false_region != nullptr) { *new_false_region = new_false; @@ -732,12 +733,20 @@ void PhaseIdealLoop::do_split_if(Node* iff, RegionNode** new_false_region, Regio DEBUG_ONLY( if (VerifyLoopOptimizations) { verify(); } ); } -void PhaseIdealLoop::pin_nodes_dependent_on(Node* ctrl) { +void PhaseIdealLoop::pin_nodes_dependent_on(Node* ctrl, bool old_iff_is_rangecheck) { for (DUIterator i = ctrl->outs(); ctrl->has_out(i); i++) { Node* use = ctrl->out(i); if (!use->depends_only_on_test()) { continue; } + + // When a RangeCheckNode is folded because its condition is a constant, IfProjNode::Identity + // returns the control input of the RangeCheckNode. As a result, when the old IfNode is not a + // RangeCheckNode, and a Load output of it depends_only_on_test, we don't need to pin the Load. + if (use->is_Load() && !old_iff_is_rangecheck) { + continue; + } + Node* pinned_clone = use->pin_node_under_control(); register_new_node_with_ctrl_of(pinned_clone, use); _igvn.replace_node(use, pinned_clone);