@@ -2463,7 +2463,7 @@ bool PhaseIdealLoop::is_scaled_iv_plus_extra_offset(Node* exp1, Node* offset3, N
24632463
24642464// ------------------------------do_range_check---------------------------------
24652465// Eliminate range-checks and other trip-counter vs loop-invariant tests.
2466- void PhaseIdealLoop::do_range_check (IdealLoopTree *loop, Node_List &old_new ) {
2466+ void PhaseIdealLoop::do_range_check (IdealLoopTree* loop ) {
24672467#ifndef PRODUCT
24682468 if (PrintOpto && VerifyLoopOptimizations) {
24692469 tty->print (" Range Check Elimination " );
@@ -2526,8 +2526,9 @@ void PhaseIdealLoop::do_range_check(IdealLoopTree *loop, Node_List &old_new) {
25262526 // Range check elimination optimizes out conditions whose parameters are loop invariant in the main loop. They usually
25272527 // have control above the pre loop, but there's no guarantee that they do. There's no guarantee either that the pre
25282528 // loop limit has control that's out of loop (a previous round of range check elimination could have set a limit that's
2529- // not loop invariant).
2530- Node* new_limit_ctrl = dominated_node (pre_ctrl, pre_limit_ctrl);
2529+ // not loop invariant). new_limit_ctrl is used for both the pre and main loops. Early control for the main limit may be
2530+ // below the pre loop entry and the pre limit and must be taken into account when initializing new_limit_ctrl.
2531+ Node* new_limit_ctrl = dominated_node (pre_ctrl, pre_limit_ctrl, compute_early_ctrl (main_limit, main_limit_ctrl));
25312532
25322533 // Ensure the original loop limit is available from the
25332534 // pre-loop Opaque1 node.
@@ -2778,8 +2779,10 @@ void PhaseIdealLoop::do_range_check(IdealLoopTree *loop, Node_List &old_new) {
27782779 // new pre_limit can push Bool/Cmp/Opaque nodes down (when one of the eliminated condition has parameters that are not
27792780 // loop invariant in the pre loop.
27802781 set_ctrl (pre_opaq, new_limit_ctrl);
2781- set_ctrl (pre_end->cmp_node (), new_limit_ctrl);
2782- set_ctrl (pre_end->in (1 ), new_limit_ctrl);
2782+ // Can't use new_limit_ctrl for Bool/Cmp because it can be out of loop while they are loop variant. Conservatively set
2783+ // control to latest possible one.
2784+ set_ctrl (pre_end->cmp_node (), pre_end->in (0 ));
2785+ set_ctrl (pre_end->in (1 ), pre_end->in (0 ));
27832786
27842787 _igvn.replace_input_of (pre_opaq, 1 , pre_limit);
27852788
@@ -2819,11 +2822,12 @@ void PhaseIdealLoop::do_range_check(IdealLoopTree *loop, Node_List &old_new) {
28192822 // The OpaqueNode is unshared by design
28202823 assert (opqzm->outcnt () == 1 , " cannot hack shared node" );
28212824 _igvn.replace_input_of (opqzm, 1 , main_limit);
2822- // new main_limit can push Bool/Cmp nodes down (when one of the eliminated condition has parameters that are not loop
2823- // invariant in the pre loop.
2825+ // new main_limit can push opaque node for zero trip guard down (when one of the eliminated condition has parameters
2826+ // that are not loop invariant in the pre loop) .
28242827 set_ctrl (opqzm, new_limit_ctrl);
2825- set_ctrl (iffm->in (1 )->in (1 ), new_limit_ctrl);
2826- set_ctrl (iffm->in (1 ), new_limit_ctrl);
2828+ // Bool/Cmp nodes for zero trip guard should have been assigned control between the main and pre loop (because zero
2829+ // trip guard depends on induction variable value out of pre loop) so shouldn't need to be adjusted
2830+ assert (is_dominator (new_limit_ctrl, get_ctrl (iffm->in (1 )->in (1 ))), " control of cmp should be below control of updated input" );
28272831
28282832 C->print_method (PHASE_AFTER_RANGE_CHECK_ELIMINATION, 4 , cl);
28292833}
@@ -3402,7 +3406,7 @@ bool IdealLoopTree::iteration_split_impl(PhaseIdealLoop *phase, Node_List &old_n
34023406 // with full checks, but the main-loop with no checks. Remove said checks
34033407 // from the main body.
34043408 if (should_rce) {
3405- phase->do_range_check (this , old_new );
3409+ phase->do_range_check (this );
34063410 }
34073411
34083412 // Double loop body for unrolling. Adjust the minimum-trip test (will do
0 commit comments