https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100499
--- Comment #10 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to bin cheng from comment #9) > Seems we have a long standing bug in fold-const.c:multiple_of_p in case of > wrapping types. Take unsigned int as an example: > (0xfffffffc * 0x3) % 0x3 = 0x1 > But multiple_of_p returns true here. > > The same issue also stands for MINUS_EXPR and PLUS_EXPR. Given > multiple_of_p is used elsewhere, the fix might break existing optimizations. > Especially, number of loop iterations is computed in unsigned types multiple_of_p is mostly used in contexts where overflow "cannot happen" (in TYPE/DECL_SIZE computation context), and in niter analysis it seems to be guarded similarly. This restriction of multiple_of_p seems undocumented, so fixing that might be good. Now, you don't say what's the chain of events that lead to a multiple_of_p call eventually leading to the wrong answer, but I guess it's the code added under the + if (!niter->control.no_overflow + && (integer_onep (s) || multiple_of_p (type, c, s))) check as !niter->control.no_overflow seems to suggest that the multiple_of_p check is not properly guarded?