On Wed, Nov 26, 2025 at 09:52:50AM +0100, Richard Biener wrote: > I wonder if it makes sense to wrap > get_range_query (cfun)->range_of_expr (r, @0, gimple_match_ctx (@4)) > into sth like gimple_match_range_of_expr (r, @0, @4)?
It does make sense, so the following patch implements that. Note, gimple-match.h is a bad location for that helper, because lots of users use it without having value-range.h included and it is for APIs to use the gimple folders, not for match.pd helpers themselves, so I've moved there gimple_match_ctx as well. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2025-11-27 Jakub Jelinek <[email protected]> PR tree-optimization/119683 * gimple-match.h (gimple_match_ctx): Move to ... * gimple-match-head.cc (gimple_match_ctx): ... here. Make static. (gimple_match_range_of_expr): New static inline. * match.pd ((mult (plus:s (mult:s @0 @1) @2) @3)): Use gimple_match_range_of_expr. ((plus (mult:s (plus:s @0 @1) @2) @3): Likewise. ((t * u) / u -> t): Likewise. ((t * u) / v -> t * (u / v)): Likewise. ((X + M*N) / N -> X / N + M): Likewise. ((X - M*N) / N -> X / N - M): Likewise. ((X + C) / N -> X / N + C / N): Likewise. (((T)(A)) + CST -> (T)(A + CST)): Likewise (x_5 == cstN ? cst4 : cst3): Likewise. Do r.set_varying even when gimple_match_range_of_expr failed. --- gcc/gimple-match.h.jj 2025-11-26 10:57:29.339204790 +0100 +++ gcc/gimple-match.h 2025-11-26 11:41:16.137194895 +0100 @@ -427,17 +427,4 @@ bool directly_supported_p (code_helper, internal_fn get_conditional_internal_fn (code_helper, tree); -/* If OP is a SSA_NAME with SSA_NAME_DEF_STMT in the IL, return that - stmt, otherwise NULL. For use in range_of_expr calls. */ - -inline gimple * -gimple_match_ctx (tree op) -{ - if (TREE_CODE (op) == SSA_NAME - && SSA_NAME_DEF_STMT (op) - && gimple_bb (SSA_NAME_DEF_STMT (op))) - return SSA_NAME_DEF_STMT (op); - return NULL; -} - #endif /* GCC_GIMPLE_MATCH_H */ --- gcc/gimple-match-head.cc.jj 2025-04-08 14:08:51.645276381 +0200 +++ gcc/gimple-match-head.cc 2025-11-26 11:42:01.122414073 +0100 @@ -507,3 +507,29 @@ match_cond_with_binary_phi (gphi *phi, t return cond; } + +/* If OP is a SSA_NAME with SSA_NAME_DEF_STMT in the IL, return that + stmt, otherwise NULL. For use in range_of_expr calls. */ + +static inline gimple * +gimple_match_ctx (tree op) +{ + if (TREE_CODE (op) == SSA_NAME + && SSA_NAME_DEF_STMT (op) + && gimple_bb (SSA_NAME_DEF_STMT (op))) + return SSA_NAME_DEF_STMT (op); + return NULL; +} + +/* Helper to shorten range queries in match.pd. R is the range to + be queried, OP tree on which it should be queried and CTX is some + capture on which gimple_match_ctx should be called, or NULL for + global range. */ + +static inline bool +gimple_match_range_of_expr (vrange &r, tree op, tree ctx = NULL_TREE) +{ + return get_range_query (cfun)->range_of_expr (r, op, + ctx ? gimple_match_ctx (ctx) + : NULL); +} --- gcc/match.pd.jj 2025-11-26 10:57:29.339986214 +0100 +++ gcc/match.pd 2025-11-26 11:36:22.901286265 +0100 @@ -661,8 +661,7 @@ (define_operator_list SYNC_FETCH_AND_AND #if GIMPLE int_range_max vr0; if (ovf1 == wi::OVF_NONE && ovf2 == wi::OVF_NONE - && get_range_query (cfun)->range_of_expr (vr0, @4, - gimple_match_ctx (@5)) + && gimple_match_range_of_expr (vr0, @4, @5) && !vr0.varying_p () && !vr0.undefined_p ()) { wide_int wmin0 = vr0.lower_bound (); @@ -703,8 +702,7 @@ (define_operator_list SYNC_FETCH_AND_AND #if GIMPLE int_range_max vr0; if (ovf1 == wi::OVF_NONE && ovf2 == wi::OVF_NONE - && get_range_query (cfun)->range_of_expr (vr0, @0, - gimple_match_ctx (@4)) + && gimple_match_range_of_expr (vr0, @0, @4) && !vr0.varying_p () && !vr0.undefined_p ()) { wide_int wmin0 = vr0.lower_bound (); @@ -1025,10 +1023,8 @@ (define_operator_list SYNC_FETCH_AND_AND #if GIMPLE (with {int_range_max vr0, vr1;} (if (INTEGRAL_TYPE_P (type) - && get_range_query (cfun)->range_of_expr (vr0, @0, - gimple_match_ctx (@2)) - && get_range_query (cfun)->range_of_expr (vr1, @1, - gimple_match_ctx (@2)) + && gimple_match_range_of_expr (vr0, @0, @2) + && gimple_match_range_of_expr (vr1, @1, @2) && range_op_handler (MULT_EXPR).overflow_free_p (vr0, vr1)) @0)) #endif @@ -1042,9 +1038,8 @@ (define_operator_list SYNC_FETCH_AND_AND (if (TYPE_OVERFLOW_UNDEFINED (type) && !TYPE_OVERFLOW_SANITIZED (type)) (mult @0 (div! @1 @2)) (with {int_range_max vr0, vr1;} - (if (get_range_query (cfun)->range_of_expr (vr0, @0, - gimple_match_ctx (@3)) - && get_range_query (cfun)->range_of_expr (vr1, @1) + (if (gimple_match_range_of_expr (vr0, @0, @3) + && gimple_match_range_of_expr (vr1, @1) && range_op_handler (MULT_EXPR).overflow_free_p (vr0, vr1)) (mult @0 (div! @1 @2)))) ))) @@ -1058,10 +1053,9 @@ (define_operator_list SYNC_FETCH_AND_AND (div @1 @2) #if GIMPLE (with {int_range_max vr0, vr1, vr2;} - (if (get_range_query (cfun)->range_of_expr (vr0, @0, - gimple_match_ctx (@3)) - && get_range_query (cfun)->range_of_expr (vr1, @1) - && get_range_query (cfun)->range_of_expr (vr2, @2) + (if (gimple_match_range_of_expr (vr0, @0, @3) + && gimple_match_range_of_expr (vr1, @1) + && gimple_match_range_of_expr (vr2, @2) && range_op_handler (MULT_EXPR).overflow_free_p (vr0, vr1) && range_op_handler (MULT_EXPR).overflow_free_p (vr0, vr2)) (div @1 @2))) @@ -1075,19 +1069,15 @@ (define_operator_list SYNC_FETCH_AND_AND (div (plus:c@4 @0 (mult:c@3 @1 @2)) @2) (with {int_range_max vr0, vr1, vr2, vr3, vr4;} (if (INTEGRAL_TYPE_P (type) - && get_range_query (cfun)->range_of_expr (vr1, @1, - gimple_match_ctx (@3)) - && get_range_query (cfun)->range_of_expr (vr2, @2, - gimple_match_ctx (@3)) + && gimple_match_range_of_expr (vr1, @1, @3) + && gimple_match_range_of_expr (vr2, @2, @3) /* "N*M" doesn't overflow. */ && range_op_handler (MULT_EXPR).overflow_free_p (vr1, vr2) - && get_range_query (cfun)->range_of_expr (vr0, @0, - gimple_match_ctx (@4)) - && get_range_query (cfun)->range_of_expr (vr3, @3, - gimple_match_ctx (@4)) + && gimple_match_range_of_expr (vr0, @0, @4) + && gimple_match_range_of_expr (vr3, @3, @4) /* "X+(N*M)" doesn't overflow. */ && range_op_handler (PLUS_EXPR).overflow_free_p (vr0, vr3) - && get_range_query (cfun)->range_of_expr (vr4, @4) + && gimple_match_range_of_expr (vr4, @4) && !vr4.undefined_p () /* "X+N*M" is not with opposite sign as "X". */ && (TYPE_UNSIGNED (type) @@ -1100,19 +1090,15 @@ (define_operator_list SYNC_FETCH_AND_AND (div (minus@4 @0 (mult:c@3 @1 @2)) @2) (with {int_range_max vr0, vr1, vr2, vr3, vr4;} (if (INTEGRAL_TYPE_P (type) - && get_range_query (cfun)->range_of_expr (vr1, @1, - gimple_match_ctx (@3)) - && get_range_query (cfun)->range_of_expr (vr2, @2, - gimple_match_ctx (@3)) + && gimple_match_range_of_expr (vr1, @1, @3) + && gimple_match_range_of_expr (vr2, @2, @3) /* "N * M" doesn't overflow. */ && range_op_handler (MULT_EXPR).overflow_free_p (vr1, vr2) - && get_range_query (cfun)->range_of_expr (vr0, @0, - gimple_match_ctx (@4)) - && get_range_query (cfun)->range_of_expr (vr3, @3, - gimple_match_ctx (@4)) + && gimple_match_range_of_expr (vr0, @0, @4) + && gimple_match_range_of_expr (vr3, @3, @4) /* "X - (N*M)" doesn't overflow. */ && range_op_handler (MINUS_EXPR).overflow_free_p (vr0, vr3) - && get_range_query (cfun)->range_of_expr (vr4, @4) + && gimple_match_range_of_expr (vr4, @4) && !vr4.undefined_p () /* "X-N*M" is not with opposite sign as "X". */ && (TYPE_UNSIGNED (type) @@ -1138,13 +1124,12 @@ (define_operator_list SYNC_FETCH_AND_AND int_range_max vr0, vr1, vr3; } (if (INTEGRAL_TYPE_P (type) - && get_range_query (cfun)->range_of_expr (vr0, @0, - gimple_match_ctx (@3))) + && gimple_match_range_of_expr (vr0, @0, @3)) (if (exact_mod (c) - && get_range_query (cfun)->range_of_expr (vr1, @1) + && gimple_match_range_of_expr (vr1, @1) /* "X+C" doesn't overflow. */ && range_op_handler (PLUS_EXPR).overflow_free_p (vr0, vr1) - && get_range_query (cfun)->range_of_expr (vr3, @3) + && gimple_match_range_of_expr (vr3, @3) && !vr3.undefined_p () /* "X+C" and "X" are not of opposite sign. */ && (TYPE_UNSIGNED (type) @@ -4484,8 +4469,7 @@ (define_operator_list SYNC_FETCH_AND_AND TYPE_SIGN (inner_type)); int_range_max vr; - if (get_range_query (cfun)->range_of_expr (vr, @0, - gimple_match_ctx (@2)) + if (gimple_match_range_of_expr (vr, @0, @2) && !vr.varying_p () && !vr.undefined_p ()) { wide_int wmin0 = vr.lower_bound (); @@ -6563,8 +6547,8 @@ (define_operator_list SYNC_FETCH_AND_AND || wi::to_widest (@2) == wi::to_widest (@3) + 1)) (with { int_range_max r; - get_range_query (cfun)->range_of_expr (r, @0, gimple_match_ctx (@4)); - if (r.undefined_p ()) + if (!gimple_match_range_of_expr (r, @0, @4) + || r.undefined_p ()) r.set_varying (TREE_TYPE (@0)); wide_int min = r.lower_bound (); Jakub
