On Mon, Jan 16, 2023 at 08:19:25AM +0100, Richard Biener wrote: > + // If op1 and op2 are equivalences, then we don't need a complete cross > + // product, just pairs of matching elements. > + if (relation_equiv_p (rel) && lh == rh && num_lh <= 16) > + { > + int_range_max tmp; > + r.set_undefined (); > + for (unsigned x = 0; x < num_lh; ++x) > + { > + wide_int lh_lb = lh.lower_bound (x); > + wide_int lh_ub = lh.upper_bound (x); > + wi_fold_in_parts_equiv (tmp, type, lh_lb, lh_ub); > > and that does > > + widest_int lh_range = wi::sub (widest_int::from (lh_ub, TYPE_SIGN (type)), > + widest_int::from (lh_lb, TYPE_SIGN (type))); > + // if there are 1 to 8 values in the LH range, split them up. > + r.set_undefined (); > + if (lh_range >= 0 && lh_range <= 7) > + { > + for (unsigned x = 0; x <= lh_range; x++) > > which in total limits the number of sub-ranges in the output but in an > odd way. It's also all-or-nothing. IIRC there's a hard limit on the > number of sub-ranges in the output anyway via int_range<N>, so > why not use that and always do the first loop over the sub-ranges > of the inputs and the second loop over the range members but > stop when we reach N-1 and then use wi_fold on the remainds? > > Your above code suggests we go up to 112 sub-ranges and once > we'd reach 113 we'd fold down to a single. > > Maybe my "heuristic" wouldn't be much better, but then somehow > breaking the heuristic down to a single magic number would be > better, esp. since .union_ will undo some of the breakup when > reaching N?
The <= X in the first case is what I've suggested, the previous behavior didn't suffer from this all or nothing case, but I was worried because the behavior is that we create many subranges and then in the end just merge the last ones into a single subrange such that it fits into the limit. So we could create 255 * 8 subranges and then merge the last 255 * 7 + 1 into one. We could call that wi_fold_in_parts_equiv only if r.num_parts () < m_max_ranges and wi_fold otherwise... Jakub