https://gcc.gnu.org/g:d151a11ee04ff11fb9378434b1e223aae22edd66
commit r16-5647-gd151a11ee04ff11fb9378434b1e223aae22edd66 Author: Jakub Jelinek <[email protected]> Date: Thu Nov 27 11:57:02 2025 +0100 fold-const, match.pd: Pass stmt to expr_not_equal if possible The following patch is a small extension of the previous patch to pass stmt context to the ranger queries from match.pd where possible, so that we can use local ranges on a particular statement rather than global ones. expr_not_equal_to also uses the ranger, so when possible this passes it the statement context. 2025-11-27 Jakub Jelinek <[email protected]> * fold-const.h (expr_not_equal_to): Add gimple * argument defaulted to NULL. * fold-const.cc (expr_not_equal_to): Likewise, pass it through to range_of_expr. * generic-match-head.cc (gimple_match_ctx): New static inline. * match.pd (X % -Y -> X % Y): Capture NEGATE and pass gimple_match_ctx (@2) as new 3rd argument to expr_not_equal_to. ((A * C) +- (B * C) -> (A+-B) * C): Pass gimple_match_ctx (@3) as new 3rd argument to expr_not_equal_to. (a rrotate (bitsize-b) -> a lrotate b): Likewise. Diff: --- gcc/fold-const.cc | 8 +++++--- gcc/fold-const.h | 2 +- gcc/generic-match-head.cc | 6 ++++++ gcc/match.pd | 28 ++++++++++++++++++---------- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index 85e7da595c6a..535377737f3e 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -10938,10 +10938,12 @@ tree_expr_nonzero_p (tree t) return ret; } -/* Return true if T is known not to be equal to an integer W. */ +/* Return true if T is known not to be equal to an integer W. + If STMT is specified, the check is if T on STMT is not equal + to W. */ bool -expr_not_equal_to (tree t, const wide_int &w) +expr_not_equal_to (tree t, const wide_int &w, gimple *stmt /* = NULL */) { int_range_max vr; switch (TREE_CODE (t)) @@ -10953,7 +10955,7 @@ expr_not_equal_to (tree t, const wide_int &w) if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) return false; - get_range_query (cfun)->range_of_expr (vr, t); + get_range_query (cfun)->range_of_expr (vr, t, stmt); if (!vr.undefined_p () && !vr.contains_p (w)) return true; /* If T has some known zero bits and W has any of those bits set, diff --git a/gcc/fold-const.h b/gcc/fold-const.h index 149992d1f107..c80dbcff32f7 100644 --- a/gcc/fold-const.h +++ b/gcc/fold-const.h @@ -223,7 +223,7 @@ extern bool merge_ranges (int *, tree *, tree *, int, tree, tree, int, extern tree sign_bit_p (tree, const_tree); extern bool simple_condition_p (tree); extern tree exact_inverse (tree, tree); -extern bool expr_not_equal_to (tree t, const wide_int &); +extern bool expr_not_equal_to (tree t, const wide_int &, gimple * = NULL); extern tree const_unop (enum tree_code, tree, tree); extern tree vector_const_binop (enum tree_code, tree, tree, tree (*) (enum tree_code, tree, tree)); diff --git a/gcc/generic-match-head.cc b/gcc/generic-match-head.cc index ea4a958686db..1a9b490f2ee9 100644 --- a/gcc/generic-match-head.cc +++ b/gcc/generic-match-head.cc @@ -203,3 +203,9 @@ bitwise_inverted_equal_p (tree expr1, tree expr2, bool &wascmp) } return false; } + +static inline gimple * +gimple_match_ctx (tree) +{ + return NULL; +} diff --git a/gcc/match.pd b/gcc/match.pd index c76238a27f76..fec546a29ed1 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -918,7 +918,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* X % -Y is the same as X % Y. */ (simplify - (trunc_mod @0 (convert? (negate @1))) + (trunc_mod @0 (convert? (negate@2 @1))) (if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type) && !TYPE_OVERFLOW_TRAPS (type) @@ -928,7 +928,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) INT_MIN % -(-1) into invalid INT_MIN % -1. */ && (expr_not_equal_to (@0, wi::to_wide (TYPE_MIN_VALUE (type))) || expr_not_equal_to (@1, wi::minus_one (TYPE_PRECISION - (TREE_TYPE (@1)))))) + (TREE_TYPE (@1))), + gimple_match_ctx (@2)))) (trunc_mod @0 (convert @1)))) /* X - (X / Y) * Y is the same as X % Y. */ @@ -4695,7 +4696,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) || TYPE_OVERFLOW_WRAPS (type) || (INTEGRAL_TYPE_P (type) && tree_expr_nonzero_p (@0) - && expr_not_equal_to (@0, wi::minus_one (TYPE_PRECISION (type))))) + && expr_not_equal_to (@0, wi::minus_one (TYPE_PRECISION (type)), + gimple_match_ctx (@3)))) (if (single_use (@3) || single_use (@4)) /* If @1 +- @2 is constant require a hard single-use on either original operand (but not on both). */ @@ -4715,16 +4717,19 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) || (INTEGRAL_TYPE_P (type) && ((tree_expr_nonzero_p (@0) && expr_not_equal_to (@0, - wi::minus_one (TYPE_PRECISION (type)))) + wi::minus_one (TYPE_PRECISION (type)), + gimple_match_ctx (@3))) || (plusminus == PLUS_EXPR ? expr_not_equal_to (@2, - wi::max_value (TYPE_PRECISION (type), SIGNED)) + wi::max_value (TYPE_PRECISION (type), SIGNED), + gimple_match_ctx (@3)) /* Let's ignore the @0 -1 and @2 min case. */ : (expr_not_equal_to (@2, - wi::min_value (TYPE_PRECISION (type), SIGNED)) + wi::min_value (TYPE_PRECISION (type), SIGNED), + gimple_match_ctx (@3)) && expr_not_equal_to (@2, wi::min_value (TYPE_PRECISION (type), SIGNED) - + 1)))))) + + 1, gimple_match_ctx (@3))))))) && single_use (@3)) (mult (plusminus { build_one_cst (type); } @2) @0))) (simplify @@ -4739,11 +4744,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) && ((tree_expr_nonzero_p (@0) && (plusminus == MINUS_EXPR || expr_not_equal_to (@0, - wi::minus_one (TYPE_PRECISION (type))))) + wi::minus_one (TYPE_PRECISION (type)), + gimple_match_ctx (@3)))) || expr_not_equal_to (@2, (plusminus == PLUS_EXPR ? wi::max_value (TYPE_PRECISION (type), SIGNED) - : wi::min_value (TYPE_PRECISION (type), SIGNED)))))) + : wi::min_value (TYPE_PRECISION (type), SIGNED)), + gimple_match_ctx (@3))))) && single_use (@3)) (mult (plusminus @2 { build_one_cst (type); }) @0))))) /* (A * B) + (-C) -> (B - C/A) * A, if C is a multiple of A. */ @@ -5344,7 +5351,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (prec == wi::to_wide (@1)) (switch (if (expr_not_equal_to (@2, wi::uhwi (prec, - TYPE_PRECISION (TREE_TYPE (@2))))) + TYPE_PRECISION (TREE_TYPE (@2))), + gimple_match_ctx (@3))) (orotate @0 @2)) (if (single_use (@3) && pow2p_hwi (prec)
