From 40fd269ab128d1f5fa7688d7d5e7298744c08cdd Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Sun, 20 Nov 2016 16:32:37 +0100 Subject: [PATCH] Simplify X /[ex] 8 == 0 2016-11-20 Marc Glisse gcc/ * fold-const.c (fold_comparison): Ignore EXACT_DIV_EXPR. * match.pd (A /[ex] B CMP C): New simplifications. gcc/testsuite/ * gcc.dg/tree-ssa/cmpexactdiv.c: New file. From-SVN: r242638 --- gcc/ChangeLog | 5 ++++ gcc/fold-const.c | 3 +-- gcc/match.pd | 30 +++++++++++++++++++++ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv.c | 21 +++++++++++++++ 5 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c64b3492b75..d02d6e5b536 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2016-11-20 Marc Glisse + + * fold-const.c (fold_comparison): Ignore EXACT_DIV_EXPR. + * match.pd (A /[ex] B CMP C): New simplifications. + 2016-11-20 Marc Glisse * match.pd (0 / X, X / X, X % X): New simplifications. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index f4b2cfa743e..3c5a77ee654 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -8700,8 +8700,7 @@ fold_comparison (location_t loc, enum tree_code code, tree type, /* We can fold X/C1 op C2 where C1 and C2 are integer constants into a single range test. */ - if ((TREE_CODE (arg0) == TRUNC_DIV_EXPR - || TREE_CODE (arg0) == EXACT_DIV_EXPR) + if (TREE_CODE (arg0) == TRUNC_DIV_EXPR && TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST && !integer_zerop (TREE_OPERAND (arg0, 1)) diff --git a/gcc/match.pd b/gcc/match.pd index f97a99888ca..36270d0b108 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -2351,6 +2351,36 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (ge @0 { build_real (TREE_TYPE (@0), dconst0); }) (cmp @0 { build_real (TREE_TYPE (@0), c2); })))))))))))) +/* Fold A /[ex] B CMP C to A CMP B * C. */ +(for cmp (eq ne) + (simplify + (cmp (exact_div @0 @1) INTEGER_CST@2) + (if (!integer_zerop (@1)) + (if (wi::eq_p (@2, 0)) + (cmp @0 @2) + (if (TREE_CODE (@1) == INTEGER_CST) + (with + { + bool ovf; + wide_int prod = wi::mul (@2, @1, TYPE_SIGN (TREE_TYPE (@1)), &ovf); + } + (if (ovf) + { constant_boolean_node (cmp == NE_EXPR, type); } + (cmp @0 { wide_int_to_tree (TREE_TYPE (@0), prod); })))))))) +(for cmp (lt le gt ge) + (simplify + (cmp (exact_div @0 INTEGER_CST@1) INTEGER_CST@2) + (if (wi::gt_p (@1, 0, TYPE_SIGN (TREE_TYPE (@1)))) + (with + { + bool ovf; + wide_int prod = wi::mul (@2, @1, TYPE_SIGN (TREE_TYPE (@1)), &ovf); + } + (if (ovf) + { constant_boolean_node (wi::lt_p (@2, 0, TYPE_SIGN (TREE_TYPE (@2))) + != (cmp == LT_EXPR || cmp == LE_EXPR), type); } + (cmp @0 { wide_int_to_tree (TREE_TYPE (@0), prod); })))))) + /* Unordered tests if either argument is a NaN. */ (simplify (bit_ior (unordered @0 @0) (unordered @1 @1)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c20d91d85c8..2c81bf439ad 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-11-20 Marc Glisse + + * gcc.dg/tree-ssa/cmpexactdiv.c: New file. + 2016-11-20 Andre Vehreschild PR fortran/78395 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv.c b/gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv.c new file mode 100644 index 00000000000..48e5cda3442 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/cmpexactdiv.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +int f(int *p, int *q){ + __SIZE_TYPE__ n = q - p; + return n == 0; +} + +int g(int *p, int *q){ + __PTRDIFF_TYPE__ n = q - p; + return n <= 2; +} + +int h(long *p, long *q){ + __SIZE_TYPE__ n = q - p; + return n == (__SIZE_TYPE__)(-1)/2; +} + +/* { dg-final { scan-tree-dump-not "== 0" "optimized" } } */ +/* { dg-final { scan-tree-dump "<= 8" "optimized" { target { int32 } } } } */ +/* { dg-final { scan-tree-dump "return 0" "optimized" } } */ -- 2.30.2