On Tue, 30 Jun 2015, Marc Glisse wrote: > On Mon, 29 Jun 2015, Marek Polacek wrote: > > > On Mon, Jun 29, 2015 at 09:36:59AM +0200, Richard Biener wrote: > > > > Anything wrong with this? > > > > > > > > +/* X - (X / Y) * Y is the same as X % Y. */ > > > > +(simplify > > > > + (minus (convert? @0) (convert? (mult (trunc_div @0 @1) @1))) > > > > + (if (INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type)) > > > > + (convert (trunc_mod @0 @1)))) > > > > That looks awfully similar to a variant I also tried (but I remember > > having convert1? and convert2? in it). Not sure what was wrong with > > that one; certainly yours seems to work fine. > > Afterwards I thought of a limitation. Nothing bad, but it highlights a trap I > regularly fall into: several @0 in the same pattern may have different types > (for INTEGER_CST, operand_equal_p mostly ignores the type). So for an int x, > 42L-42/x*x should fail to match, while using convert1? and convert2? should > match.
Indeed that's a subtle issue with using operand_equal_p for matching operands. Note that 42L-42/x*x will appear as 42L-(long)(42/x*x) in the IL just in case that wasn't obvious. Thus ok to adjust the pattern to convert1? / convert2? if you add such a testcase (maybe also add the one that the variants you tried on originally failed to match). Richard.