Marc Glisse <marc.gli...@inria.fr> writes: > On Tue, 31 Jul 2018, Richard Biener wrote: > >>>> Also, when @2 == @0 + (@1+1) then the original condition is true but >>>> ((sizetype) @0 - (sizetype) @2 + @1) > (@1 * 2) is not? >>>> (sizetype) @0 - (sizetype) (@0 + @1 + 1) + @1 > @1 * 2 >>>> -> -1 > @1 * 2 >>>> >>>> which is false. So I can't really see how you can apply this transform in >>>> general (it would be fine for generating alias checks but a bit more >>>> pessimistic). >>>> >>>> But maybe I am missing something? >>> >>> It relies on sizetype being unsigned: (sizetype)-1 > @1 * 2 is true. >> >> Hmm, so mathematically this is >> >> (@0 - @2) % modreduce + @1 > @1 * 2 >> >> then, but I don't want to think too much about this since Marc didn't >> object here ;) > > We already transform abs(x)<=3 into (unsigned)x+3u<=6u, that's the usual > way we do range checking so I didn't pay much attention to that part. > (tempted to say: "I didn't want to think too much about this since > Richard was going to do it anyway" ;-) > > Turning multiple comparisons of the form P + cst CMP Q + cst into a > range check on P - Q sounds good (we don't really have to restrict to > the case where the range is symmetric). Actually, just turning P + cst > CMP Q + cst into P - Q CMP cst should do it, we should already have code > to handle range checking on integers (modulo the issue of CSE P-Q and > Q-P). But I don't know if a couple :s is sufficient to make this > transformation a good canonicalization.
Yeah. Like you say, in the cases being handled by the patch, folding the two comparisons separately and then folding the IOR would require either (a) folding: P + cst < Q to the rather unnatural-looking: Q - P > -cst when tree_swap_operands_p (P, Q) or (b) making the range fold handle reversed pointer_diffs (which I guess makes more sense). But the fold in the patch should be either a strict win or a wash even without :s on the pointer_pluses (only realised that when doing today's respin) whereas this canonicalisation really would need the :s. So I think doing the fold on the IOR makes sense. > If we start from a comparison of pointer_plus, I think it would make > sense to use pointer_diff. > > I believe currently we try to use pointer operations (pointer_plus, > pointer_diff, lt) only for related pointers and we cast to some integer > type for wilder cases (implementation of std::less in C++ for instance). > On the other hand, in an alias check, the 2 pointers are possibly > unrelated, so maybe the code emitted for an alias check should be > changed. If we can prove that the pointers are to different objects, it would be valid to fold the check to "no alias", regardless of the constant (although in practice we should have weeded out those cases before generating the check). In that sense, relying on the UBness of comparing pointers to different objects would be fine. If there's a risk of the check being folded to "alias" when the pointers are known to point to different objects then that would be more of a problem (as a missed optimisation). Thanks, Richard