From: Jakub Jelinek Date: Thu, 13 Sep 2018 07:36:50 +0000 (+0200) Subject: re PR tree-optimization/87287 (Move signed (x % pow2) == 0 optimization to gimple) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=392750c53e09334eb509aae4db52a4db18c413be;p=gcc.git re PR tree-optimization/87287 (Move signed (x % pow2) == 0 optimization to gimple) PR tree-optimization/87287 * fold-const.c (fold_binary_loc) : Move signed modulo X % C == 0 to X % (unsigned) C == 0 optimization to ... * match.pd (X % C == 0): ... here. New optimization. * gcc.dg/tree-ssa/pr87287.c: New test. From-SVN: r264260 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6314c60aa24..7ce34fafa6f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-09-13 Jakub Jelinek + + PR tree-optimization/87287 + * fold-const.c (fold_binary_loc) : Move signed modulo + X % C == 0 to X % (unsigned) C == 0 optimization to ... + * match.pd (X % C == 0): ... here. New optimization. + 2018-09-12 Jakub Jelinek PR middle-end/82853 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 3bcf272bd63..71c18eb1e82 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -10661,28 +10661,6 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type, } } - /* If this is an NE or EQ comparison of zero against the result of a - signed MOD operation whose second operand is a power of 2, make - the MOD operation unsigned since it is simpler and equivalent. */ - if (integer_zerop (arg1) - && !TYPE_UNSIGNED (TREE_TYPE (arg0)) - && (TREE_CODE (arg0) == TRUNC_MOD_EXPR - || TREE_CODE (arg0) == CEIL_MOD_EXPR - || TREE_CODE (arg0) == FLOOR_MOD_EXPR - || TREE_CODE (arg0) == ROUND_MOD_EXPR) - && integer_pow2p (TREE_OPERAND (arg0, 1))) - { - tree newtype = unsigned_type_for (TREE_TYPE (arg0)); - tree newmod = fold_build2_loc (loc, TREE_CODE (arg0), newtype, - fold_convert_loc (loc, newtype, - TREE_OPERAND (arg0, 0)), - fold_convert_loc (loc, newtype, - TREE_OPERAND (arg0, 1))); - - return fold_build2_loc (loc, code, type, newmod, - fold_convert_loc (loc, newtype, arg1)); - } - /* Fold ((X >> C1) & C2) == 0 and ((X >> C1) & C2) != 0 where C1 is a valid shift constant, and C2 is a power of two, i.e. a single bit. */ diff --git a/gcc/match.pd b/gcc/match.pd index be669caf844..6d54dcb6f69 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -470,7 +470,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && TYPE_OVERFLOW_UNDEFINED (type) && wi::multiple_of_p (wi::to_wide (@1), wi::to_wide (@2), TYPE_SIGN (type))) - { build_zero_cst (type); }))) + { build_zero_cst (type); })) + /* For (X % C) == 0, if X is signed and C is power of 2, use unsigned + modulo and comparison, since it is simpler and equivalent. */ + (for cmp (eq ne) + (simplify + (cmp (mod @0 integer_pow2p@2) integer_zerop@1) + (if (!TYPE_UNSIGNED (TREE_TYPE (@0))) + (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); } + (cmp (mod (convert:utype @0) (convert:utype @2)) (convert:utype @1))))))) /* X % -C is the same as X % C. */ (simplify diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5a50c801203..2102f5a20d3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-09-13 Jakub Jelinek + + PR tree-optimization/87287 + * gcc.dg/tree-ssa/pr87287.c: New test. + 2018-09-12 David Malcolm PR c++/85110 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr87287.c b/gcc/testsuite/gcc.dg/tree-ssa/pr87287.c new file mode 100644 index 00000000000..cba4f43ded9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr87287.c @@ -0,0 +1,34 @@ +/* PR tree-optimization/87287 */ +/* { dg-options "-O2 -fdump-tree-cddce1" } */ +/* { dg-final { scan-tree-dump-not " % 16" "cddce1" } } */ +/* { dg-final { scan-tree-dump-times " & 15" 4 "cddce1" } } */ + +void f0 (void); + +int +f1 (int x) +{ + return x % 16 == 0; +} + +int +f2 (int x) +{ + int y = x % 16; + return y != 0; +} + +void +f3 (int x) +{ + if (x % 16 != 0) + f0 (); +} + +void +f4 (int x) +{ + int y = x % 16; + if (y == 0) + f0 (); +}