On Thu, 27 Nov 2025, Jakub Jelinek wrote: > Hi! > > 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. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Thanks, Richard. > 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. > > --- gcc/fold-const.h.jj 2025-11-24 17:17:33.860960760 +0100 > +++ gcc/fold-const.h 2025-11-26 16:16:44.155650861 +0100 > @@ -223,7 +223,7 @@ extern bool merge_ranges (int *, tree *, > 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)); > --- gcc/fold-const.cc.jj 2025-11-24 17:17:33.848960971 +0100 > +++ gcc/fold-const.cc 2025-11-26 16:16:18.700091782 +0100 > @@ -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_in > 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, > --- gcc/generic-match-head.cc.jj 2025-10-06 09:38:31.865370145 +0200 > +++ gcc/generic-match-head.cc 2025-11-26 16:22:53.872248271 +0100 > @@ -203,3 +203,9 @@ bitwise_inverted_equal_p (tree expr1, tr > } > return false; > } > + > +static inline gimple * > +gimple_match_ctx (tree) > +{ > + return NULL; > +} > --- gcc/match.pd.jj 2025-11-26 14:55:52.453747538 +0100 > +++ gcc/match.pd 2025-11-26 16:21:13.416987904 +0100 > @@ -920,7 +920,7 @@ (define_operator_list SYNC_FETCH_AND_AND > > /* 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) > @@ -930,7 +930,8 @@ (define_operator_list SYNC_FETCH_AND_AND > 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. */ > @@ -4711,7 +4712,8 @@ (define_operator_list SYNC_FETCH_AND_AND > || 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). */ > @@ -4731,16 +4733,19 @@ (define_operator_list SYNC_FETCH_AND_AND > || (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 > @@ -4755,11 +4760,13 @@ (define_operator_list SYNC_FETCH_AND_AND > && ((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. */ > @@ -5360,7 +5367,8 @@ (define_operator_list SYNC_FETCH_AND_AND > (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) > > Jakub > > -- Richard Biener <[email protected]> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)
