[Bug middle-end/69526] ivopts candidate strangeness

amker at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Jun 23 20:32:00 GMT 2016


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 rguenther@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.


More information about the Gcc-bugs mailing list