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

commit r17-4378-gedb9556068ae47e1a3cbad69249424ab7cce5b7c
Author: Andrea Pinski <[email protected]>
Date:   Fri Sep 11 17:58:42 2026 -0700

    match: `minmax (a - c, b) + c -> minmax (a, b + c)` in some cases [PR127103]
    
    This adds a pattern to optimize `minmax (a - c, b) + c` into `minmax (a, b 
+ c)` when
    `b + c` is known not to overflow.
    
    This is a simplified version from previous one where we only handle the `a 
- c` case
    rather than the generic
    
    This shows up in std::vector::push_back :
    
    ```
      # RANGE [irange] const size_type [0, 2147483647] MASK 0x7fffffff VALUE 0x0
      __room_33 = 2147483647 - _32;
    ...
      # RANGE [irange] long unsigned int [1, 2147483646] MASK 0x7fffffff VALUE 
0x0
      _35 = MIN_EXPR <__room_33, _34>;
      # RANGE [irange] long unsigned int [1, 4294967292]
      _36 = _32 + _35;
    ```
    _32 has a range of `[0, 2147483647]`, _34 has a range of `[1, 2147483646]`.
    
    This is transformed into:
    _t = _32 + _34;
    _36 = MIN_EXPR<_t, 2147483647>
    
    This then allows to remove a condition that was never could be executed too.
    
    This is currently limited to unsigned types as overflow_free_p does not tell
    me if we are going to introduce new undefined overflow; it will return true 
for
    all TYPE_OVERFLOW_UNDEFINED types.  I filed PR 127356 to add a modified 
version
    of overflow_free_p.  But since the types in push_back is unsigned this is 
enough
    for now.  When that goes in; I will combine r17-4210-g9d734bb468e714 with 
this
    pattern and remove the special case of 0.
    
    Changes since v1:
     * v2: Only handle the case where we have `a - c` as the operand to minmax.
    
    Bootstrapped and tested on x86_64-linux-gnu.
    
            PR tree-optimization/127103
    gcc/ChangeLog:
    
            * match.pd (`minmax (a - c, b) + c`): New pattern.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/tree-ssa/minmax-plus-1.c: New test.
    
    Signed-off-by: Andrea Pinski <[email protected]>

Diff:
---
 gcc/match.pd                                  | 11 ++++++++
 gcc/testsuite/gcc.dg/tree-ssa/minmax-plus-1.c | 39 +++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/gcc/match.pd b/gcc/match.pd
index 82cf6ae0a3c6..1c0393d11cde 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -532,6 +532,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (if (gimple_match_range_of_expr (vr0, @0, @2)
        && range_op_handler (PLUS_EXPR).overflow_free_p (vr0, vr0))
     (max (plus @0 @0) @1)))))
+/* minmax (a - c, b) + c -> minmax (a, b + c) if b+c don't overflow.  */
+(for minmax (min max)
+ (simplify
+  (plus:c @0 (minmax:cs@3 (minus @1 @0) @2))
+  (with { int_range_max vr0, vr2; }
+   (if (TYPE_UNSIGNED (type)
+       && gimple_match_range_of_expr (vr0, @0)
+       && gimple_match_range_of_expr (vr2, @2, @3)
+       && range_op_handler (PLUS_EXPR).overflow_free_p (vr0, vr2))
+    (minmax @1 (plus @2 @0))))))
+
 #endif
 
 /* X * 1, X / 1 -> X.  */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-plus-1.c 
b/gcc/testsuite/gcc.dg/tree-ssa/minmax-plus-1.c
new file mode 100644
index 000000000000..75067fdb962d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-plus-1.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
+/* minmax (a, b) + c -> minmax (a + c, b + c) */
+/* PR tree-optimization/127103 */
+
+__attribute__((always_inline))
+static inline unsigned
+min(unsigned a, unsigned b)
+{
+  if (a > b)
+    return b;
+  return a;
+}
+__attribute__((always_inline))
+static inline unsigned
+max(unsigned a, unsigned b)
+{
+  if (a < b)
+    return b;
+  return a;
+}
+
+unsigned f(unsigned a, unsigned t1)
+{
+  if (a > __INT_MAX__)
+    return 0;
+  unsigned t = __INT_MAX__ - a;
+  return a + min(t, a);
+}
+
+unsigned f1(unsigned a, unsigned t1)
+{
+  if (a > __INT_MAX__)
+    return 0;
+  unsigned t = __INT_MAX__ - a;
+  return a + max(t, a);
+}
+
+/* { dg-final { scan-tree-dump-times "gimple_assign <mult_expr, _\[0-9\], 
a_\[0-9\].D., 2" 2 "optimized" } } */

Reply via email to