https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100499
--- Comment #13 from bin cheng <amker at gcc dot gnu.org> --- (In reply to Richard Biener from comment #10) > (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, Oh, I am not aware of this. Actually my previous change to it seems broke this assumption already. Will see how to fix or revert the change. > 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?