Don't pin LoadNode if the old IfNode is not a RangeCheckNode

This commit is contained in:
Quan Anh Mai 2026-02-08 18:21:12 +07:00
parent ffbe66be14
commit 836a5e92d4
2 changed files with 13 additions and 4 deletions

View File

@ -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);

View File

@ -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);