https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69526
--- Comment #20 from amker at gcc dot gnu.org --- (In reply to rdapp from comment #19) > (In reply to rguent...@suse.de from comment #18) > > > > The match.pd patch is slowly assuming shape... Two things however I'm still > unsure about: > > 1. > An existing rule in match.pd checks for overflow of the combined constant > in (a +- CST1) +- CST2 and does not perform the simplification when an > overflow occurs. My case looks quite similar, however CST1 and CST2 > are/might be unsigned ints/longs. I assume this is because non-overflow > cannot be proved by the C frontend and it therefore internally uses unsigned > representation? > > (cast) (a +- CST1) +- CST2 > > We can prove the non-overflow of (a +- CST1) via VRP but an overflow check > of (CST1 +- CST2) would fail since ((UINT_MAX - 1) + 1) does overflow. IIUC we can simply handle signed/unsigned type differently. Given a has int/uint type. For unsigned case: (unsigned long long)(a + cst1) + cst2 and a is unsigned int. It can be simplified into (unsigned long long)a + cst3 iff a + cst1 doesn't overflow/wrap. Since unsigned type can wrap, simplify (unsigned long long)cst1 + cst2 into cst3 is always safe. For signed case: (long long)(a + cst) + cst2 and a is signed int. It can be simplified into (long long)a + cst3 iff (long long)cst1 + cst2 doesn't overflow. We don't need to prove (a+cst) doesn't overflow. > > So, in general, should we care about overflow of the combined operation at > all after having established the inner operation does not overflow? > If the overflow is well-defined and we overflow, the result should be valid. > If the overflow is undefined, we could do anything, in particular optimize > this which wouldn't even be too unexpected from a user's perspective. > Wouldn't any overflow in the combined constant be caused anyway, even > without combining? > > I think there are only two cases two discern, regardless of overflow: > > - abs(CST1 +- CST2) < abs(CST1), then we can simplify to (cast)(a +- (CST1 > +- CST2)) > > - else, we can simplify to (cast)(a) +- (CST1 +- CST2) > > 2. > Is there an idiomatic/correct way to check a VR_RANGE for overflow? Does it > suffice to check if the range includes +-INF or +-INF(OVF)? I suspect other, > naive methods like checking if min < max will fail, since the ranges are > canonicalized.