https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69526
rdapp at linux dot vnet.ibm.com changed: What |Removed |Added ---------------------------------------------------------------------------- Version|6.0 |unknown --- Comment #21 from rdapp at linux dot vnet.ibm.com --- (In reply to amker from comment #20) > 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. ok, the stipulation seems to be assume no signed overflow if the operation was already present but don't provoke a potentially new overflow by combining constants that previously would not have been. Makes sense. Your cases can be improved a little as Richard also pointed out: When abs(cst3) < abs(cst1) the combined operation can be done in the inner type (and the signs match so the overflow proof still holds).