https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113105
--- Comment #2 from XChy <xxs_chy at outlook dot com> --- (In reply to Jakub Jelinek from comment #1) > When it is signed v / a * b + v % a, I think it can introduce UB which > wasn't there originally. > E.g. for v = 0, a = INT_MIN and b = 3. So, if it isn't done just for > unsigned types, > parts of it need to be done in unsigned. Yes, this fold is true if there is no nooverflow/nowrap constraint. For those with nooverflow/nowrap constraint, it stays unclear to me when to fold. For your reference, LLVM expands "v % a" to "v - (v / a) * a", and then reassociates "(v / a) * b - (v / a) * a + v" to "(v / a) * (b - a) + v" to solve this issue.