[gcc r16-5646] match.pd: Introduce gimple_match_range_of_expr [PR119683]
Jakub Jelinek
jakub@gcc.gnu.org
Thu Nov 27 11:00:40 GMT 2025
https://gcc.gnu.org/g:b7169019d7d75d7bdc93cfce86ee161627df3c22
commit r16-5646-gb7169019d7d75d7bdc93cfce86ee161627df3c22
Author: Jakub Jelinek <jakub@redhat.com>
Date: Thu Nov 27 11:54:43 2025 +0100
match.pd: Introduce gimple_match_range_of_expr [PR119683]
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.
2025-11-27 Jakub Jelinek <jakub@redhat.com>
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.
Diff:
---
gcc/gimple-match-head.cc | 26 +++++++++++++++++++
gcc/gimple-match.h | 13 ----------
gcc/match.pd | 66 ++++++++++++++++++------------------------------
3 files changed, 51 insertions(+), 54 deletions(-)
diff --git a/gcc/gimple-match-head.cc b/gcc/gimple-match-head.cc
index 6b3c5febbea7..f8d0acf81462 100644
--- a/gcc/gimple-match-head.cc
+++ b/gcc/gimple-match-head.cc
@@ -507,3 +507,29 @@ match_cond_with_binary_phi (gphi *phi, tree *true_arg, tree *false_arg)
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);
+}
diff --git a/gcc/gimple-match.h b/gcc/gimple-match.h
index a2c931fa60c7..70f2f68827b4 100644
--- a/gcc/gimple-match.h
+++ b/gcc/gimple-match.h
@@ -427,17 +427,4 @@ bool directly_supported_p (code_helper, tree, tree,
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 */
diff --git a/gcc/match.pd b/gcc/match.pd
index 05c8b59eb9e8..c76238a27f76 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -661,8 +661,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
#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_INT_AND_FLOAT_ROUND_FN (RINT)
#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_INT_AND_FLOAT_ROUND_FN (RINT)
#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_INT_AND_FLOAT_ROUND_FN (RINT)
(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_INT_AND_FLOAT_ROUND_FN (RINT)
(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_INT_AND_FLOAT_ROUND_FN (RINT)
(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_INT_AND_FLOAT_ROUND_FN (RINT)
(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_INT_AND_FLOAT_ROUND_FN (RINT)
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_INT_AND_FLOAT_ROUND_FN (RINT)
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_INT_AND_FLOAT_ROUND_FN (RINT)
|| 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 ();
More information about the Gcc-cvs
mailing list