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)

Reply via email to