https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81281
--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Even the (T)P - (T)(P + A) -> -(T) A transformation looks wrong, consider A being 0U+INT_MIN, and P -1U. (int)-1U - (int)(-1U+INT_MIN) is INT_MIN without overflow, while -(int)INT_MIN overflows. Note it doesn't look like fold-const.c, at least the removed spot from it, was doing what the match.pd is doing at least for non-pointers. Note r251651 was actually the right fix, just not for this issue, but for the general issue that through performing say (int) (long_long_a - long_long_b) to (int) ((unsigned) long_long_a - (unsigned) long_long_b)) optimization we won't be able to detect UB user code had, but the optimized form doesn't. That just means that the sanitizer is less useful in finding bugs in the compiler transformations. Perhaps we could have a debug counter or param or something similar where we'd accept detecting fewer UBs on user code but gain the possibility to detect more invalid transformations like this one.