https://gcc.gnu.org/g:f48c10c6c7bda00d913dd06803e1519d1301801b

commit r17-1412-gf48c10c6c7bda00d913dd06803e1519d1301801b
Author: Naveen <[email protected]>
Date:   Sun Jun 7 21:20:42 2026 -0700

    [PATCH] tree-optimization/118680 match.pd: Fold (type)(minmax((wide)a, 
(wide)b)) -> minmax(a, b)
    
    This patch folds a min/max expression where both operands are first
    widened to a larger integer type and the result is then converted back
    to the original type.
    
    For example:
      (uint32_t) MAX_EXPR <(uint64_t) a, (uint64_t) b>
    can be folded to:
      MAX_EXPR <a, b>
    when the widening conversion preserves the signedness of the original
    type. In that case the wider min/max result is always one of the
    original operands so converting it back is unnecessary.
    
    The PR118680 match.pd simplification folds widened integer MIN/MAX
    expressions before vectorization. pr113281-5.c does not contain over-widened
    MIN_EXPR/MAX_EXPR operations for the vectorizer to narrow. Hence, the
    corresponding vectorizer dump messages are no longer emitted.
    
    Bootstrapped and tested on aarch64-linux-gnu.
    
    PR tree-optimization/118680
    
    gcc/ChangeLog:
            * match.pd: ((type) minmax (wide) a, wide (b)): New pattern.
    
    gcc/testsuite/ChangeLog:
            * gcc.dg/tree-ssa/pr118680.c: New test.
            * gcc.dg/vect/pr113281-5.c: Drop MIN_EXPR and MAX_EXPR narrowing
            dump checks that are optimized away before vectorization.
    
    Signed-off-by: Naveen <[email protected]>

Diff:
---
 gcc/match.pd                             | 15 +++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr118680.c | 33 ++++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/vect/pr113281-5.c   |  2 --
 3 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index 14567d8a1f10..e0d7ef80e14d 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4489,6 +4489,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        && !TYPE_OVERFLOW_SANITIZED (type))
     (minus (minmax @0 @1) @2))))
 
+/* (type) minmax ((wide_type) a, (wide_type) b) -> minmax (a, b)
+   when type matches the type of a and b, and wide_type is a wider
+   type with the same signedness as type. */
+(for minmax (min max)
+ (simplify
+  (convert (minmax:c (convert@2 @0) (convert@3 @1)))
+  (if (INTEGRAL_TYPE_P (type)
+       && INTEGRAL_TYPE_P (TREE_TYPE (@2))
+       && types_match (type, TREE_TYPE (@0))
+       && types_match (type, TREE_TYPE (@1))
+       && types_match (TREE_TYPE (@2), TREE_TYPE (@3))
+       && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (type)
+       && TYPE_UNSIGNED (TREE_TYPE (@2)) == TYPE_UNSIGNED (type))
+   (minmax @0 @1))))
+
 /* max (a, a + CST) -> a + CST where CST is positive.  */
 /* max (a, a + CST) -> a where CST is negative.  */
 (simplify
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr118680.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr118680.c
new file mode 100644
index 000000000000..5ce71931be5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr118680.c
@@ -0,0 +1,33 @@
+/* PR tree-optimization/118680 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+typedef __UINT32_TYPE__ uint32_t;
+typedef __UINT64_TYPE__ uint64_t;
+
+static inline uint64_t
+max_u64 (uint64_t a, uint64_t b)
+{
+  return a > b ? a : b;
+}
+
+static inline uint64_t
+min_u64 (uint64_t a, uint64_t b)
+{
+  return a < b ? a : b;
+}
+
+uint32_t
+test_max (uint32_t a, uint32_t b)
+{
+  return max_u64 (a, b);
+}
+
+uint32_t
+test_min (uint32_t a, uint32_t b)
+{
+  return min_u64 (a, b);
+}
+
+/* { dg-final { scan-tree-dump "MAX_EXPR <\[ab\]_\[0-9\]+\\(D\\), 
\[ab\]_\[0-9\]+\\(D\\)>" "optimized" } } */
+/* { dg-final { scan-tree-dump "MIN_EXPR <\[ab\]_\[0-9\]+\\(D\\), 
\[ab\]_\[0-9\]+\\(D\\)>" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr113281-5.c 
b/gcc/testsuite/gcc.dg/vect/pr113281-5.c
index 4a4571792e2a..756bf21c3804 100644
--- a/gcc/testsuite/gcc.dg/vect/pr113281-5.c
+++ b/gcc/testsuite/gcc.dg/vect/pr113281-5.c
@@ -62,5 +62,3 @@ f5 (void)
 
 /* { dg-final { scan-tree-dump {can narrow to signed:17 without loss [^\n]+= 
-} "vect" } } */
 /* { dg-final { scan-tree-dump {can narrow to signed:16 without loss [^\n]+= 
~} "vect" } } */
-/* { dg-final { scan-tree-dump {can narrow to signed:16 without loss [^\n]+ 
MIN_EXPR} "vect" } } */
-/* { dg-final { scan-tree-dump {can narrow to signed:16 without loss [^\n]+ 
MAX_EXPR} "vect" } } */

Reply via email to