1.1 --- a/src/share/vm/opto/loopTransform.cpp Fri Sep 28 14:24:22 2018 +0200 1.2 +++ b/src/share/vm/opto/loopTransform.cpp Fri Dec 14 11:22:26 2018 +0100 1.3 @@ -1537,13 +1537,20 @@ 1.4 1.5 //------------------------------adjust_limit----------------------------------- 1.6 // Helper function for add_constraint(). 1.7 -Node* PhaseIdealLoop::adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl) { 1.8 +Node* PhaseIdealLoop::adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl, bool round_up) { 1.9 // Compute "I :: (limit-offset)/scale" 1.10 Node *con = new (C) SubINode(rc_limit, offset); 1.11 register_new_node(con, pre_ctrl); 1.12 Node *X = new (C) DivINode(0, con, scale); 1.13 register_new_node(X, pre_ctrl); 1.14 1.15 + // When the absolute value of scale is greater than one, the integer 1.16 + // division may round limit down so add one to the limit. 1.17 + if (round_up) { 1.18 + X = new (C) AddINode(X, _igvn.intcon(1)); 1.19 + register_new_node(X, pre_ctrl); 1.20 + } 1.21 + 1.22 // Adjust loop limit 1.23 loop_limit = (stride_con > 0) 1.24 ? (Node*)(new (C) MinINode(loop_limit, X)) 1.25 @@ -1584,7 +1591,7 @@ 1.26 // (upper_limit-offset) may overflow or underflow. 1.27 // But it is fine since main loop will either have 1.28 // less iterations or will be skipped in such case. 1.29 - *main_limit = adjust_limit(stride_con, scale, offset, upper_limit, *main_limit, pre_ctrl); 1.30 + *main_limit = adjust_limit(stride_con, scale, offset, upper_limit, *main_limit, pre_ctrl, false); 1.31 1.32 // The underflow limit: low_limit <= scale*I+offset. 1.33 // For pre-loop compute 1.34 @@ -1620,7 +1627,8 @@ 1.35 // max(pre_limit, original_limit) is used in do_range_check(). 1.36 } 1.37 // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond); 1.38 - *pre_limit = adjust_limit((-stride_con), scale, offset, low_limit, *pre_limit, pre_ctrl); 1.39 + *pre_limit = adjust_limit((-stride_con), scale, offset, low_limit, *pre_limit, pre_ctrl, 1.40 + scale_con > 1 && stride_con > 0); 1.41 1.42 } else { // stride_con*scale_con < 0 1.43 // For negative stride*scale pre-loop checks for overflow and 1.44 @@ -1646,7 +1654,8 @@ 1.45 Node *plus_one = new (C) AddINode(offset, one); 1.46 register_new_node( plus_one, pre_ctrl ); 1.47 // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond); 1.48 - *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl); 1.49 + *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl, 1.50 + scale_con < -1 && stride_con > 0); 1.51 1.52 if (low_limit->get_int() == -max_jint) { 1.53 if (!RangeLimitCheck) return; 1.54 @@ -1681,7 +1690,8 @@ 1.55 // I > (low_limit-(offset+1))/scale 1.56 // ) 1.57 1.58 - *main_limit = adjust_limit(stride_con, scale, plus_one, low_limit, *main_limit, pre_ctrl); 1.59 + *main_limit = adjust_limit(stride_con, scale, plus_one, low_limit, *main_limit, pre_ctrl, 1.60 + false); 1.61 } 1.62 } 1.63