Skip to content

Commit cac9bbe

Browse files
martinuyRealCLanger
authored andcommitted
8320548: Improved loop handling
Backport-of: 72eed2f709caa48c82f58fe75c7e94d2c45947e1
1 parent eb7605d commit cac9bbe

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

src/hotspot/share/opto/superword.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3590,20 +3590,39 @@ void SuperWord::align_initial_loop_index(MemNode* align_to_ref) {
35903590
_igvn.register_new_node_with_optimizer(N);
35913591
_phase->set_ctrl(N, pre_ctrl);
35923592

3593+
// The computation of the new pre-loop limit could overflow or underflow the int range. This is problematic in
3594+
// combination with Range Check Elimination (RCE), which determines a "safe" range where a RangeCheck will always
3595+
// succeed. RCE adjusts the pre-loop limit such that we only enter the main-loop once we have reached the "safe"
3596+
// range, and adjusts the main-loop limit so that we exit the main-loop before we leave the "safe" range. After RCE,
3597+
// the range of the main-loop can only be safely narrowed, and should never be widened. Hence, the pre-loop limit
3598+
// can only be increased (for stride > 0), but an add overflow might decrease it, or decreased (for stride < 0), but
3599+
// a sub underflow might increase it. To prevent that, we perform the Sub / Add and Max / Min with long operations.
3600+
lim0 = new ConvI2LNode(lim0);
3601+
N = new ConvI2LNode(N);
3602+
orig_limit = new ConvI2LNode(orig_limit);
3603+
_igvn.register_new_node_with_optimizer(lim0);
3604+
_igvn.register_new_node_with_optimizer(N);
3605+
_igvn.register_new_node_with_optimizer(orig_limit);
3606+
35933607
// substitute back into (1), so that new limit
35943608
// lim = lim0 + N
35953609
Node* lim;
35963610
if (stride < 0) {
3597-
lim = new SubINode(lim0, N);
3611+
lim = new SubLNode(lim0, N);
35983612
} else {
3599-
lim = new AddINode(lim0, N);
3613+
lim = new AddLNode(lim0, N);
36003614
}
36013615
_igvn.register_new_node_with_optimizer(lim);
36023616
_phase->set_ctrl(lim, pre_ctrl);
36033617
Node* constrained =
3604-
(stride > 0) ? (Node*) new MinINode(lim, orig_limit)
3605-
: (Node*) new MaxINode(lim, orig_limit);
3618+
(stride > 0) ? (Node*) new MinLNode(_phase->C, lim, orig_limit)
3619+
: (Node*) new MaxLNode(_phase->C, lim, orig_limit);
36063620
_igvn.register_new_node_with_optimizer(constrained);
3621+
3622+
// We know that the result is in the int range, there is never truncation
3623+
constrained = new ConvL2INode(constrained);
3624+
_igvn.register_new_node_with_optimizer(constrained);
3625+
36073626
_phase->set_ctrl(constrained, pre_ctrl);
36083627
_igvn.replace_input_of(pre_opaq, 1, constrained);
36093628
}

0 commit comments

Comments
 (0)