diff --git a/src/hotspot/share/opto/ifnode.cpp b/src/hotspot/share/opto/ifnode.cpp index 6ae62b24b3c8d..0dad48ffc73f7 100644 --- a/src/hotspot/share/opto/ifnode.cpp +++ b/src/hotspot/share/opto/ifnode.cpp @@ -1015,7 +1015,7 @@ bool IfNode::fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* f const TypeInt* type2 = filtered_int_type(igvn, n, fail); if (type2 != nullptr) { failtype = failtype->join(type2)->is_int(); - if (failtype->_lo > failtype->_hi) { + if (failtype->empty()) { // previous if determines the result of this if so // replace Bool with constant igvn->replace_input_of(this, 1, igvn->intcon(success->_con)); @@ -1023,55 +1023,49 @@ bool IfNode::fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* f } } } - lo = nullptr; - hi = nullptr; + return false; + } + + assert(lo != nullptr && hi != nullptr, "sanity"); + Node* hook = new Node(lo); // Add a use to lo to prevent him from dying + // Merge the two compares into a single unsigned compare by building (CmpU (n - lo) (hi - lo)) + Node* adjusted_val = igvn->transform(new SubINode(n, lo)); + if (adjusted_lim == nullptr) { + adjusted_lim = igvn->transform(new SubINode(hi, lo)); } + hook->destruct(igvn); - if (lo && hi) { - Node* hook = new Node(1); - hook->init_req(0, lo); // Add a use to lo to prevent him from dying - // Merge the two compares into a single unsigned compare by building (CmpU (n - lo) (hi - lo)) - Node* adjusted_val = igvn->transform(new SubINode(n, lo)); - if (adjusted_lim == nullptr) { - adjusted_lim = igvn->transform(new SubINode(hi, lo)); + if (igvn->type(adjusted_lim)->is_int()->_lo < 0 && + !igvn->C->post_loop_opts_phase()) { + // If range check elimination applies to this comparison, it includes code to protect from overflows that may + // cause the main loop to be skipped entirely. Delay this transformation. + // Example: + // for (int i = 0; i < limit; i++) { + // if (i < max_jint && i > min_jint) {... + // } + // Comparisons folded as: + // i - min_jint - 1 outcnt() == 0) { + igvn->remove_dead_node(adjusted_val); } - hook->destruct(igvn); - - int lo = igvn->type(adjusted_lim)->is_int()->_lo; - if (lo < 0) { - // If range check elimination applies to this comparison, it includes code to protect from overflows that may - // cause the main loop to be skipped entirely. Delay this transformation. - // Example: - // for (int i = 0; i < limit; i++) { - // if (i < max_jint && i > min_jint) {... - // } - // Comparisons folded as: - // i - min_jint - 1 C->post_loop_opts_phase()) { - if (adjusted_val->outcnt() == 0) { - igvn->remove_dead_node(adjusted_val); - } - if (adjusted_lim->outcnt() == 0) { - igvn->remove_dead_node(adjusted_lim); - } - igvn->C->record_for_post_loop_opts_igvn(this); - return false; - } + if (adjusted_lim->outcnt() == 0) { + igvn->remove_dead_node(adjusted_lim); } + igvn->C->record_for_post_loop_opts_igvn(this); + return false; + } - Node* newcmp = igvn->transform(new CmpUNode(adjusted_val, adjusted_lim)); - Node* newbool = igvn->transform(new BoolNode(newcmp, cond)); + Node* newcmp = igvn->transform(new CmpUNode(adjusted_val, adjusted_lim)); + Node* newbool = igvn->transform(new BoolNode(newcmp, cond)); - igvn->replace_input_of(dom_iff, 1, igvn->intcon(proj->_con)); - igvn->replace_input_of(this, 1, newbool); + igvn->replace_input_of(dom_iff, 1, igvn->intcon(proj->_con)); + igvn->replace_input_of(this, 1, newbool); - return true; - } - return false; + return true; } // Merge the branches that trap for this If and the dominating If into