On Tue, Nov 9, 2021 at 5:12 AM Navid Rahimi via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > Hi GCC community, > > This patch will add the missed pattern described in bug 102232 [1] to the > match.pd. The testcase will test whether the multiplication and division has > been removed from the code or not. The correctness proof for this pattern is > here [2] in case anyone is curious. > > PR tree-optimization/102232 > * match.pd (x * (1 + y / x) - y) -> (x - y % x): New optimization.
+/* x * (1 + y / x) - y -> x - y % x */ +(simplify + (minus (mult:cs @0 (plus:cs integer_onep (trunc_div:s @1 @0))) @1) the canonical order of the plus is (plus:s (trunc_div ...) integer_onep) as constants come last - you can then remove the 'c' + (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)) you can use INTEGRAL_TYPE_P (type). + && types_match (@0, @1)) this test is not necessary + (minus @0 (trunc_mod @1 @0)))) But should we also optimize x * (2 + y/x) - y -> 2*x - y % x? So it looks like a conflict with the x * (1 + b) <-> x + x * b transform (fold_plusminus_mult)? That said, the special case of one definitely makes the result cheaper (one less operation). Please move the pattern next to the most relatest which I think is /* X - (X / Y) * Y is the same as X % Y. */ (simplify (minus (convert1? @0) (convert2? (mult:c (trunc_div @@0 @@1) @1))) (if (INTEGRAL_TYPE_P (type) || VECTOR_INTEGER_TYPE_P (type)) (convert (trunc_mod @0 @1)))) +int +main (void) +{ + // few randomly generated test cases + if (foo (71856034, 238) != 212) + { + return 1; the return value of 1 is an unreliable way to fail, please instead call __builtin_abort (); +/* { dg-options "-O3 -fdump-tree-optimized" } */ do we really need -O3 for this? I think that -O should be enough here? Thanks, Richard. > * gcc.dg/tree-ssa/pr102232.c: testcase for this optimization. > > > 1) https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102232 > 2) https://alive2.llvm.org/ce/z/2VScjD > > Best wishes, > Navid.