https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114932
--- Comment #12 from rguenther at suse dot de <rguenther at suse dot de> --- On Wed, 5 Jun 2024, tnfchris at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114932 > > --- Comment #11 from Tamar Christina <tnfchris at gcc dot gnu.org> --- > (In reply to Richard Biener from comment #10) > > I think the question is why IVOPTs ends up using both the signed and > > unsigned variant of the same IV instead of expressing all uses of both with > > one IV? > > > > That's where I'd look into. > > It looks like this is because of a subtle difference in the expressions. > > In get_loop_invariant_expr IVOPTs first tries to strip away all casts with > STRIP_NOPS. > > The first expression is (unsigned long) (stride.3_27 * 4) and the second > expression is ((unsigned long) stride.3_27) * 4 (The pretty printing here is > pretty bad...) > > So the first one becomes: > (unsigned long) (stride.3_27 * 4) -> stride.3_27 * 4 > > and second one: > ((unsigned long) stride.3_27) * 4 -> ((unsigned long) stride.3_27) * 4 > > since we don't care about overflow here, it looks like the stripping should > be recursive as long as it's a NOP expression between two integral types. > > That would get them to hash to the same IV expression. Trying now.. Note tree-affine is a tool that's used for this kind of "weak" equalities. Convert both to affine, subtract them and if that's zero they are equal.