https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80815
--- Comment #4 from amker at gcc dot gnu.org ---
Also the three cases:
/* If the left segment does not extend beyond the start of the
right segment the new segment length is that of the right
plus the segment distance. */
if (tree_fits_uhwi_p (dr_a1->seg_len)
&& compare_tree_int (dr_a1->seg_len, diff) <= 0)
{
dr_a1->seg_len = size_binop (PLUS_EXPR, dr_a2->seg_len,
size_int (diff));
do_remove = true;
}
/* Generally the new segment length is the maximum of the
left segment size and the right segment size plus the distance.
??? We can also build tree MAX_EXPR here but it's not clear this
is profitable. */
else if (tree_fits_uhwi_p (dr_a1->seg_len)
&& tree_fits_uhwi_p (dr_a2->seg_len))
{
unsigned HOST_WIDE_INT seg_len_a1 = tree_to_uhwi
(dr_a1->seg_len);
unsigned HOST_WIDE_INT seg_len_a2 = tree_to_uhwi
(dr_a2->seg_len);
dr_a1->seg_len = size_int (MAX (seg_len_a1, diff + seg_len_a2));
do_remove = true;
}
/* Now we check if the following condition is satisfied:
DIFF - SEGMENT_LENGTH_A < SEGMENT_LENGTH_B
where DIFF = DR_A2_INIT - DR_A1_INIT. However,
SEGMENT_LENGTH_A or SEGMENT_LENGTH_B may not be constant so we
have to make a best estimation. We can get the minimum value
of SEGMENT_LENGTH_B as a constant, represented by MIN_SEG_LEN_B,
then either of the following two conditions can guarantee the
one above:
1: DIFF <= MIN_SEG_LEN_B
2: DIFF - SEGMENT_LENGTH_A < MIN_SEG_LEN_B */
else
{
unsigned HOST_WIDE_INT min_seg_len_b
= (tree_fits_uhwi_p (dr_b1->seg_len)
? tree_to_uhwi (dr_b1->seg_len)
: factor);
if (diff <= min_seg_len_b
|| (tree_fits_uhwi_p (dr_a1->seg_len)
&& diff - tree_to_uhwi (dr_a1->seg_len) < min_seg_len_b))
{
dr_a1->seg_len = size_binop (PLUS_EXPR,
dr_a2->seg_len, size_int
(diff));
do_remove = true;
}
}
Can be merged together. the merged dr_a1->seg_len is dr_a2->seg_len + diff,
with an exception checking MAX (seg_len_a1, diff + seg_len_a2).
Of course, negative step still needs to be handled.