This is a follow on r16-4534-g07800a565abd20 based on the review of
the other pattern 
(https://gcc.gnu.org/pipermail/gcc-patches/2025-October/698336.html)
as the same issue mentioned in that review apply here.

This changes to use the new version of minmax_from_comparison so we don't need 
to create
a tree for the constant. and use wi::mask instead of TYPE_MIN_VALUE.

gcc/ChangeLog:

        * match.pd (`(type1)x CMP CST1 ? (type2)x : CST2`): Better handling
        of `((signed)x) < 0`.

Signed-off-by: Andrew Pinski <[email protected]>
---
 gcc/match.pd | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index cbf03512b71..b1882b14050 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -6571,25 +6571,30 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
      tree from_type = TREE_TYPE (@1);
      tree c1_type = TREE_TYPE (@3), c2_type = TREE_TYPE (@2);
      enum tree_code code = ERROR_MARK;
-     enum tree_code ncmp = cmp;
-     tree c1 = @3;
 
      /* `((signed)a) < 0` should be converted back into
         `a >= (unsigned)SIGNED_TYPE_MIN`.
        `((signed)a) >= 0` should be converted back into
        `a < (unsigned)SIGNED_TYPE_MIN`. */
-     if (integer_zerop (c1)
+     if (integer_zerop (@3)
+         && INTEGRAL_TYPE_P (from_type)
          && (cmp == GE_EXPR || cmp == LT_EXPR)
         && TYPE_UNSIGNED (from_type)
         && !TYPE_UNSIGNED (c1_type)
-        && TYPE_PRECISION (from_type) == TYPE_PRECISION (c1_type))
+        && TYPE_PRECISION (from_type) == TYPE_PRECISION (c1_type)
+        && int_fits_type_p (@2, from_type)
+        && (types_match (c2_type, from_type)
+            || (TYPE_PRECISION (c2_type) > TYPE_PRECISION (from_type)
+                && (TYPE_UNSIGNED (from_type)
+                    || TYPE_SIGN (c2_type) == TYPE_SIGN (from_type)))))
        {
-         ncmp = cmp == GE_EXPR ? LT_EXPR : GE_EXPR;
-         c1 = fold_convert (from_type, TYPE_MIN_VALUE (c1_type));
-         c1_type = from_type;
+         tree_code ncmp = cmp == GE_EXPR ? LE_EXPR : GT_EXPR;
+         widest_int c1 = wi::mask<widest_int>(TYPE_PRECISION (type) - 1, 0);
+         code = minmax_from_comparison (ncmp, @1, c1, wi::to_widest (@2));
        }
 
-     if (INTEGRAL_TYPE_P (from_type)
+     if (code == ERROR_MARK
+         && INTEGRAL_TYPE_P (from_type)
         && int_fits_type_p (@2, from_type)
         && (types_match (c1_type, from_type)
             || (TYPE_PRECISION (c1_type) > TYPE_PRECISION (from_type)
@@ -6600,8 +6605,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
                 && (TYPE_UNSIGNED (from_type)
                     || TYPE_SIGN (c2_type) == TYPE_SIGN (from_type)))))
        {
-        if (ncmp != EQ_EXPR)
-          code = minmax_from_comparison (ncmp, @1, c1, @1, @2);
+        if (cmp != EQ_EXPR)
+          code = minmax_from_comparison (cmp, @1, @3, @1, @2);
         /* Can do A == C1 ? A : C2  ->  A == C1 ? C1 : C2?  */
         else if (int_fits_type_p (@3, from_type))
           code = EQ_EXPR;
-- 
2.43.0

Reply via email to