From: Samarth Tandale <[email protected]>

The pattern:

        x == C ? y : min (x, y)

can be simplified to min (x, y) whenever C >= upper_bound (y),
because min (C, y) == y for all values y can take.  Similarly:

        x == C ? y : max (x, y)

can be simplified to max (x, y) whenever C <= lower_bound (y).

Use ranger to query the value range of y and check the bound condition.

        PR tree-optimization/125700

gcc/ChangeLog:
        PR tree-optimization/125700
        * match.pd ((x == C) ? y : MIN/MAX (x, y)): New simplification.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/pr125700.c: New test.
        * gcc.dg/tree-ssa/pr125700-int-width.c: New test.
        * gcc.dg/tree-ssa/pr125700-negative.c: New test.
        * gcc.dg/tree-ssa/pr125700-range.c: New test.

Signed-off-by: Samarth Tandale <[email protected]>
---
For MIN_EXPR, if x is TYPE_MAX_VALUE, then min (x, y) is y.
So:
        x == TYPE_MAX_VALUE ? y : min (x, y)
can be simplified to:
        min (x, y)

Similarly for MAX_EXPR, if x is TYPE_MIN_VALUE, then max (x, y)
is y.
So:
        x == TYPE_MIN_VALUE ? y : max (x, y)
can be simplified to:
        max (x, y)

This adds a combined match.pd pattern for MIN_EXPR and MAX_EXPR.

        PR tree-optimization/125700

```
gcc/ChangeLog:

        * match.pd: Fold type-bound guarded min/max expressions.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/pr125700.c: New test.
        * gcc.dg/tree-ssa/pr125700-int-width.c: New test.
        * gcc.dg/tree-ssa/pr125700-negative.c: New test.
        * gcc.dg/tree-ssa/pr125700-range.c: New test.
```

Signed-off-by: Samarth Tandale <[email protected]>

Changes since v1:
- Extended the optimization beyond fixed type limits. It now handles constants 
when Ranger proves their relationship with y's value range and conservatively 
falls back when no useful range is available.
- Added positive and negative test cases for Ranger-derived ranges.



This is a forge pull request published on the gcc-patches mailing list mailing 
list
as requested by Samarth Tandale via Sourceware Forge 
<[email protected]>.
Forge discussion: https://forge.sourceware.org/gcc/gcc/pulls/214

Get it locally using:
```
git fetch forge-upstream "+refs/versioned_pull/214/*:refs/versioned_pull/214/*"
git switch -c "pr-214-v2" "refs/versioned_pull/214/2/head"
```
Or, download the patch at: https://forge.sourceware.org/gcc/gcc/pulls/214.diff
Created on: 2026-08-10 06:22:31+00:00
Latest update: 2026-09-19 10:29:08+00:00
Changes: 5 changed files, 407 additions, 0 deletions
Head revision: sam-100/gcc ref pr125700 commit 
7e709962d4f3c68b0f6f2522c743109a0d11aeea 
Base revision: gcc/gcc ref trunk commit 
7f405dfaa29e4c9d8c7b4e6ada13fa44ff053a0c r17-4446-g7f405dfaa29e4c
Merge base: 7f405dfaa29e4c9d8c7b4e6ada13fa44ff053a0c
Requested Reviewers: pinskia

Changed files:
- A: gcc/testsuite/gcc.dg/tree-ssa/pr125700-int-width.c
- A: gcc/testsuite/gcc.dg/tree-ssa/pr125700-negative.c
- A: gcc/testsuite/gcc.dg/tree-ssa/pr125700-range.c
- A: gcc/testsuite/gcc.dg/tree-ssa/pr125700.c
- M: gcc/match.pd

 gcc/match.pd                                  |  25 +++
 .../gcc.dg/tree-ssa/pr125700-int-width.c      |  51 +++++++
 .../gcc.dg/tree-ssa/pr125700-negative.c       |  70 +++++++++
 .../gcc.dg/tree-ssa/pr125700-range.c          | 144 ++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr125700.c      | 117 ++++++++++++++
 5 files changed, 407 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr125700-int-width.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr125700-negative.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr125700-range.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr125700.c

diff --git a/gcc/match.pd b/gcc/match.pd
index e59c11d5d131d..857dc9a6baa29 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -13596,3 +13596,28 @@ and,
  (if (INTEGRAL_TYPE_P (type))
    (with { tree itype = TREE_TYPE (@2); }
     (convert (minus @2 (convert:itype @1))))))
+
+#if GIMPLE
+/* Replace (x == C) ? y : MIN (x, y) -> MIN (x, y) when C >= upper_bound (y),
+   and (x == C) ? y : MAX (x, y) -> MAX (x, y) when C <= lower_bound (y),
+   because in both cases the guarded arm equals the min/max expression.  */
+(for minmax (min max)
+ (simplify
+  (cond (eq @0 INTEGER_CST@1) @2 (minmax:c@3 @0 @2))
+  (if (INTEGRAL_TYPE_P (type))
+   (with {
+     int_range_max r;
+     if (!gimple_match_range_of_expr (r, @2, @2))
+       r.set_varying (TREE_TYPE (@2));
+     wide_int bound;
+     if (minmax == MIN_EXPR)
+       bound = r.upper_bound ();
+     else
+       bound = r.lower_bound ();
+    }
+   (if ((minmax == MIN_EXPR
+        && wi::ge_p (wi::to_wide (@1), bound, TYPE_SIGN (type)))
+       || (minmax == MAX_EXPR
+           && wi::le_p (wi::to_wide (@1), bound, TYPE_SIGN (type))))
+    @3)))))
+#endif
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr125700-int-width.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr125700-int-width.c
new file mode 100644
index 0000000000000..a203fdb01189c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr125700-int-width.c
@@ -0,0 +1,51 @@
+/* PR tree-optimization/125700  */
+/* Integer width variants to cover non-int widths and both signed/unsigned.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+#include <limits.h>
+
+#define GEN_FUNCS(TAG, UTYPE, STYPE, UMAX, SMAX, SMIN) \
+UTYPE \
+fumin_##TAG (UTYPE x, UTYPE y) \
+{ \
+  if (x == (UMAX)) \
+    return y; \
+  return x < y ? x : y; \
+} \
+\
+STYPE \
+fsmin_##TAG (STYPE x, STYPE y) \
+{ \
+  if (x == (SMAX)) \
+    return y; \
+  return x < y ? x : y; \
+} \
+\
+UTYPE \
+fumax_##TAG (UTYPE x, UTYPE y) \
+{ \
+  if (x == 0) \
+    return y; \
+  return x > y ? x : y; \
+} \
+\
+STYPE \
+fsmax_##TAG (STYPE x, STYPE y) \
+{ \
+  if (x == (SMIN)) \
+    return y; \
+  return x > y ? x : y; \
+}
+
+GEN_FUNCS (char, unsigned char, signed char, UCHAR_MAX, SCHAR_MAX, SCHAR_MIN)
+GEN_FUNCS (short, unsigned short, short, USHRT_MAX, SHRT_MAX, SHRT_MIN)
+GEN_FUNCS (long, unsigned long, long, ULONG_MAX, LONG_MAX, LONG_MIN)
+GEN_FUNCS (long_long, unsigned long long, long long, ULLONG_MAX, LLONG_MAX,
+    LLONG_MIN)
+
+/* { dg-final { scan-tree-dump-not {if \(} "optimized" } } */
+/* { dg-final { scan-tree-dump-not " == " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 8 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 8 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr125700-negative.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr125700-negative.c
new file mode 100644
index 0000000000000..2cfa280a138b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr125700-negative.c
@@ -0,0 +1,70 @@
+/* PR tree-optimization/125700  */
+/* Negative test cases, should not transform.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+unsigned
+fumin_negative (unsigned x, unsigned y)
+{
+  if (x == 0)
+    return y;
+  return x < y ? x : y;
+}
+
+unsigned
+fumax_negative (unsigned x, unsigned y)
+{
+  if (x == -1u)
+    return y;
+  return x > y ? x : y;
+}
+
+signed
+fsmin_negative (signed x, signed y)
+{
+  if (x == -__INT_MAX__ - 1)
+    return y;
+  return x < y ? x : y;
+}
+
+signed
+fsmax_negative (signed x, signed y)
+{
+  if (x == __INT_MAX__)
+    return y;
+  return x > y ? x : y;
+}
+
+/* Unsigned char widened to unsigned int.  */
+unsigned
+fumin_range_negative (unsigned char a, unsigned int b)
+{
+  unsigned aa = a;
+  if (aa == 255)
+    return b;
+  return aa < b ? aa : b;
+}
+
+/* Signed char widened to int.  */
+int
+fsmin_range_negative (signed char a, signed int b)
+{
+  int aa = a;
+  if (aa == 127)
+    return b;
+  return aa < b ? aa : b;
+}
+
+int
+fsmax_range_negative (signed char a, signed int b)
+{
+  int aa = a;
+  if (aa == -128)
+    return b;
+  return aa > b ? aa : b;
+}
+
+/* None of the if and '==' comparisons should be eliminated.  */
+/* { dg-final { scan-tree-dump-times {if \(} 7 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " == " 7 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr125700-range.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr125700-range.c
new file mode 100644
index 0000000000000..d474162d5ceb0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr125700-range.c
@@ -0,0 +1,144 @@
+/* PR tree-optimization/125700  */
+/* Test that the optimization fires using Ranger-derived value ranges,
+   including ranges from widened types and range-limiting operations.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+/* Unsigned char widened to unsigned int.  */
+unsigned
+fumin_char_range (unsigned char a, unsigned char b)
+{
+  unsigned aa = a;
+  unsigned bb = b;
+  if (aa == 255)
+    return bb;
+  return aa < bb ? aa : bb;
+}
+
+unsigned
+fumax_char_range (unsigned char a, unsigned char b)
+{
+  unsigned aa = a;
+  unsigned bb = b;
+  if (aa == 0)
+    return bb;
+  return aa > bb ? aa : bb;
+}
+
+/* Signed char widened to int.  */
+int
+fsmin_char_range (signed char a, signed char b)
+{
+  int aa = a;
+  int bb = b;
+  if (aa == 127)
+    return bb;
+  return aa < bb ? aa : bb;
+}
+
+int
+fsmax_char_range (signed char a, signed char b)
+{
+  int aa = a;
+  int bb = b;
+  if (aa == -128)
+    return bb;
+  return aa > bb ? aa : bb;
+}
+
+/* C is strictly above the upper bound of y's value range for MIN,
+   and strictly below the lower bound for MAX.  */
+unsigned
+fumin_range_above_bound (unsigned x, unsigned y)
+{
+  if (y > 100)
+    y = 100;
+  if (x == 120)
+    return y;
+  return x < y ? x : y;
+}
+
+unsigned
+fumax_range_below_bound (unsigned x, unsigned y)
+{
+  y &= 127;
+  if (y < 27)
+    y = 27;
+  if (x == 10)
+    return y;
+  return x > y ? x : y;
+}
+
+int
+fsmin_range_above_bound (int x, int y)
+{
+  y &= 127;
+  if (y > 100)
+    y = 100;
+  if (x == 120)
+    return y;
+  return x < y ? x : y;
+}
+
+int
+fsmax_range_below_bound (int x, int y)
+{
+  y &= 127;
+  if (y < 27)
+    y = 27;
+  if (x == 10)
+    return y;
+  return x > y ? x : y;
+}
+
+/* C is equal to the upper bound of y's value range for MIN,
+   and equal to the lower bound for MAX.  */
+unsigned
+fumin_range_at_bound (unsigned x, unsigned y)
+{
+  y &= 127;
+  if (y > 100)
+    y = 100;
+  if (x == 100)
+    return y;
+  return x < y ? x : y;
+}
+
+unsigned
+fumax_range_at_bound (unsigned x, unsigned y)
+{
+  y &= 127;
+  if (y < 27)
+    y = 27;
+  if (x == 27)
+    return y;
+  return x > y ? x : y;
+}
+
+int
+fsmin_range_at_bound (int x, int y)
+{
+  y &= 127;
+  if (y > 100)
+    y = 100;
+  if (x == 100)
+    return y;
+  return x < y ? x : y;
+}
+
+int
+fsmax_range_at_bound (int x, int y)
+{
+  y &= 127;
+  if (y < 27)
+    y = 27;
+  if (x == 27)
+    return y;
+  return x > y ? x : y;
+}
+
+/* { dg-final { scan-tree-dump-not {if \(} "optimized" } } */
+/* { dg-final { scan-tree-dump-not " == " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 10 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 10 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr125700.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr125700.c
new file mode 100644
index 0000000000000..397c72544355b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr125700.c
@@ -0,0 +1,117 @@
+/* PR tree-optimization/125700  */
+/* Test the original cases, alternative condition forms and reversed
+   minimum/maximum operand orders.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+/* Base test cases.  */
+unsigned
+fumin (unsigned x, unsigned y)
+{
+  if (x == -1u)
+    return y;
+  return x < y ? x : y;
+}
+
+signed
+fsmin (signed x, signed y)
+{
+  if (x == __INT_MAX__)
+    return y;
+  return x < y ? x : y;
+}
+
+unsigned
+fumax (unsigned x, unsigned y)
+{
+  if (x == 0)
+    return y;
+  return x > y ? x : y;
+}
+
+signed
+fsmax (signed x, signed y)
+{
+  if (x == -__INT_MAX__ - 1)
+    return y;
+  return x > y ? x : y;
+}
+
+/* Conditional operator variants.  */
+unsigned
+fumin_ne (unsigned x, unsigned y)
+{
+  if (x != -1u)
+    return x < y ? x : y;
+  return y;
+}
+
+unsigned
+fumax_ne (unsigned x, unsigned y)
+{
+  if (x != 0)
+    return x > y ? x : y;
+  return y;
+}
+
+unsigned
+fumin_ge (unsigned x, unsigned y)
+{
+  if (x >= -1u)
+    return y;
+  return x < y ? x : y;
+}
+
+unsigned
+fumax_le (unsigned x, unsigned y)
+{
+  if (x <= 0)
+    return y;
+  return x > y ? x : y;
+}
+
+unsigned
+fumin_lt (unsigned x, unsigned y)
+{
+  if (!(x < -1u))
+    return y;
+  return x < y ? x : y;
+}
+
+unsigned
+fumax_gt (unsigned x, unsigned y)
+{
+  if (!(x > 0))
+    return y;
+  return x > y ? x : y;
+}
+
+/* Commutativity tests for min/max operator.  */
+unsigned
+fumin_flip (unsigned x, unsigned y)
+{
+  if (x == -1u)
+    return y;
+  return y > x ? x : y;
+}
+
+unsigned
+fumax_flip (unsigned x, unsigned y)
+{
+  if (x == 0)
+    return y;
+  return y < x ? x : y;
+}
+
+/* The if and all conditional operators should be removed
+   from the optimized dump output.  */
+/* { dg-final { scan-tree-dump-not {if \(} "optimized" } } */
+/* { dg-final { scan-tree-dump-not " == " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " != " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " <= " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " >= " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " < " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " > " "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 6 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 6 "optimized" } } */

Range-diff against v1:
1:  4d042112a6061 ! 1:  7e709962d4f3c match: Simplify type-bound guarded 
min/max expressions [PR125700]
    @@ Metadata
     Author: Samarth Tandale <[email protected]>
     
      ## Commit message ##
    -    match: Simplify type-bound guarded min/max expressions [PR125700]
    +    match: Simplify value-range guarded min/max expressions [PR125700]
     
    -    For MIN_EXPR, if x is TYPE_MAX_VALUE, then min (x, y) is y.
    -    So:
    -            x == TYPE_MAX_VALUE ? y : min (x, y)
    -    can be simplified to:
    -            min (x, y)
    +    The pattern:
     
    -    Similarly for MAX_EXPR, if x is TYPE_MIN_VALUE, then max (x, y)
    -    is y.
    -    So:
    -            x == TYPE_MIN_VALUE ? y : max (x, y)
    -    can be simplified to:
    -            max (x, y)
    +            x == C ? y : min (x, y)
     
    -    This adds a combined match.pd pattern for MIN_EXPR and MAX_EXPR.
    +    can be simplified to min (x, y) whenever C >= upper_bound (y),
    +    because min (C, y) == y for all values y can take.  Similarly:
    +
    +            x == C ? y : max (x, y)
    +
    +    can be simplified to max (x, y) whenever C <= lower_bound (y).
    +
    +    Use ranger to query the value range of y and check the bound condition.
     
                 PR tree-optimization/125700
     
         gcc/ChangeLog:
    -
    -            * match.pd: Fold type-bound guarded min/max expressions.
    +            PR tree-optimization/125700
    +            * match.pd ((x == C) ? y : MIN/MAX (x, y)): New simplification.
     
         gcc/testsuite/ChangeLog:
     
                 * gcc.dg/tree-ssa/pr125700.c: New test.
                 * gcc.dg/tree-ssa/pr125700-int-width.c: New test.
                 * gcc.dg/tree-ssa/pr125700-negative.c: New test.
    +            * gcc.dg/tree-ssa/pr125700-range.c: New test.
     
         Signed-off-by: Samarth Tandale <[email protected]>
     
    @@ gcc/match.pd: and,
         (with { tree itype = TREE_TYPE (@2); }
          (convert (minus @2 (convert:itype @1))))))
     +
    -+/* Replace (x == TYPE_MAX) ? y : MIN (x, y) -> MIN (x, y)
    -+   because MIN (TYPE_MAX, y) is always y.
    -+   Similarly, (x == TYPE_MIN) ? y : MAX (x, y) -> MAX (x, y)
    -+   because MAX (TYPE_MIN, y) is always y.  */
    ++#if GIMPLE
    ++/* Replace (x == C) ? y : MIN (x, y) -> MIN (x, y) when C >= upper_bound 
(y),
    ++   and (x == C) ? y : MAX (x, y) -> MAX (x, y) when C <= lower_bound (y),
    ++   because in both cases the guarded arm equals the min/max expression.  
*/
     +(for minmax (min max)
     + (simplify
     +  (cond (eq @0 INTEGER_CST@1) @2 (minmax:c@3 @0 @2))
     +  (if (INTEGRAL_TYPE_P (type))
     +   (with {
    -+     tree bound = (minmax == MIN_EXPR)
    -+            ? TYPE_MAX_VALUE (type)
    -+            : TYPE_MIN_VALUE (type);
    ++     int_range_max r;
    ++     if (!gimple_match_range_of_expr (r, @2, @2))
    ++       r.set_varying (TREE_TYPE (@2));
    ++     wide_int bound;
    ++     if (minmax == MIN_EXPR)
    ++       bound = r.upper_bound ();
    ++     else
    ++       bound = r.lower_bound ();
     +    }
    -+    (if (bound && tree_int_cst_equal (@1, bound))
    -+     @3)))))
    ++   (if ((minmax == MIN_EXPR
    ++   && wi::ge_p (wi::to_wide (@1), bound, TYPE_SIGN (type)))
    ++  || (minmax == MAX_EXPR
    ++      && wi::le_p (wi::to_wide (@1), bound, TYPE_SIGN (type))))
    ++    @3)))))
    ++#endif
     
      ## gcc/testsuite/gcc.dg/tree-ssa/pr125700-int-width.c (new) ##
     @@
     +/* PR tree-optimization/125700  */
    -+/* Integer width variants to cover non-int widths and
    -+   both signed/unsigned.  */
    ++/* Integer width variants to cover non-int widths and both 
signed/unsigned.  */
     +
     +/* { dg-do compile } */
     +/* { dg-options "-O1 -fdump-tree-optimized" } */
    @@ gcc/testsuite/gcc.dg/tree-ssa/pr125700-int-width.c (new)
     +GEN_FUNCS (long_long, unsigned long long, long long, ULLONG_MAX, 
LLONG_MAX,
     +    LLONG_MIN)
     +
    -+/* { dg-final { scan-tree-dump-not "if" "optimized" } } */
    ++/* { dg-final { scan-tree-dump-not {if \(} "optimized" } } */
     +/* { dg-final { scan-tree-dump-not " == " "optimized" } } */
     +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 8 "optimized" } } */
     +/* { dg-final { scan-tree-dump-times "MAX_EXPR" 8 "optimized" } } */
    @@ gcc/testsuite/gcc.dg/tree-ssa/pr125700-negative.c (new)
     +  return x > y ? x : y;
     +}
     +
    ++/* Unsigned char widened to unsigned int.  */
    ++unsigned
    ++fumin_range_negative (unsigned char a, unsigned int b)
    ++{
    ++  unsigned aa = a;
    ++  if (aa == 255)
    ++    return b;
    ++  return aa < b ? aa : b;
    ++}
    ++
    ++/* Signed char widened to int.  */
    ++int
    ++fsmin_range_negative (signed char a, signed int b)
    ++{
    ++  int aa = a;
    ++  if (aa == 127)
    ++    return b;
    ++  return aa < b ? aa : b;
    ++}
    ++
    ++int
    ++fsmax_range_negative (signed char a, signed int b)
    ++{
    ++  int aa = a;
    ++  if (aa == -128)
    ++    return b;
    ++  return aa > b ? aa : b;
    ++}
    ++
     +/* None of the if and '==' comparisons should be eliminated.  */
    -+/* { dg-final { scan-tree-dump-times "if" 4 "optimized" } } */
    -+/* { dg-final { scan-tree-dump-times " == " 4 "optimized" } } */
    ++/* { dg-final { scan-tree-dump-times {if \(} 7 "optimized" } } */
    ++/* { dg-final { scan-tree-dump-times " == " 7 "optimized" } } */
    +
    + ## gcc/testsuite/gcc.dg/tree-ssa/pr125700-range.c (new) ##
    +@@
    ++/* PR tree-optimization/125700  */
    ++/* Test that the optimization fires using Ranger-derived value ranges,
    ++   including ranges from widened types and range-limiting operations.  */
    ++
    ++/* { dg-do compile } */
    ++/* { dg-options "-O1 -fdump-tree-optimized" } */
    ++
    ++/* Unsigned char widened to unsigned int.  */
    ++unsigned
    ++fumin_char_range (unsigned char a, unsigned char b)
    ++{
    ++  unsigned aa = a;
    ++  unsigned bb = b;
    ++  if (aa == 255)
    ++    return bb;
    ++  return aa < bb ? aa : bb;
    ++}
    ++
    ++unsigned
    ++fumax_char_range (unsigned char a, unsigned char b)
    ++{
    ++  unsigned aa = a;
    ++  unsigned bb = b;
    ++  if (aa == 0)
    ++    return bb;
    ++  return aa > bb ? aa : bb;
    ++}
    ++
    ++/* Signed char widened to int.  */
    ++int
    ++fsmin_char_range (signed char a, signed char b)
    ++{
    ++  int aa = a;
    ++  int bb = b;
    ++  if (aa == 127)
    ++    return bb;
    ++  return aa < bb ? aa : bb;
    ++}
    ++
    ++int
    ++fsmax_char_range (signed char a, signed char b)
    ++{
    ++  int aa = a;
    ++  int bb = b;
    ++  if (aa == -128)
    ++    return bb;
    ++  return aa > bb ? aa : bb;
    ++}
    ++
    ++/* C is strictly above the upper bound of y's value range for MIN,
    ++   and strictly below the lower bound for MAX.  */
    ++unsigned
    ++fumin_range_above_bound (unsigned x, unsigned y)
    ++{
    ++  if (y > 100)
    ++    y = 100;
    ++  if (x == 120)
    ++    return y;
    ++  return x < y ? x : y;
    ++}
    ++
    ++unsigned
    ++fumax_range_below_bound (unsigned x, unsigned y)
    ++{
    ++  y &= 127;
    ++  if (y < 27)
    ++    y = 27;
    ++  if (x == 10)
    ++    return y;
    ++  return x > y ? x : y;
    ++}
    ++
    ++int
    ++fsmin_range_above_bound (int x, int y)
    ++{
    ++  y &= 127;
    ++  if (y > 100)
    ++    y = 100;
    ++  if (x == 120)
    ++    return y;
    ++  return x < y ? x : y;
    ++}
    ++
    ++int
    ++fsmax_range_below_bound (int x, int y)
    ++{
    ++  y &= 127;
    ++  if (y < 27)
    ++    y = 27;
    ++  if (x == 10)
    ++    return y;
    ++  return x > y ? x : y;
    ++}
    ++
    ++/* C is equal to the upper bound of y's value range for MIN,
    ++   and equal to the lower bound for MAX.  */
    ++unsigned
    ++fumin_range_at_bound (unsigned x, unsigned y)
    ++{
    ++  y &= 127;
    ++  if (y > 100)
    ++    y = 100;
    ++  if (x == 100)
    ++    return y;
    ++  return x < y ? x : y;
    ++}
    ++
    ++unsigned
    ++fumax_range_at_bound (unsigned x, unsigned y)
    ++{
    ++  y &= 127;
    ++  if (y < 27)
    ++    y = 27;
    ++  if (x == 27)
    ++    return y;
    ++  return x > y ? x : y;
    ++}
    ++
    ++int
    ++fsmin_range_at_bound (int x, int y)
    ++{
    ++  y &= 127;
    ++  if (y > 100)
    ++    y = 100;
    ++  if (x == 100)
    ++    return y;
    ++  return x < y ? x : y;
    ++}
    ++
    ++int
    ++fsmax_range_at_bound (int x, int y)
    ++{
    ++  y &= 127;
    ++  if (y < 27)
    ++    y = 27;
    ++  if (x == 27)
    ++    return y;
    ++  return x > y ? x : y;
    ++}
    ++
    ++/* { dg-final { scan-tree-dump-not {if \(} "optimized" } } */
    ++/* { dg-final { scan-tree-dump-not " == " "optimized" } } */
    ++/* { dg-final { scan-tree-dump-times "MIN_EXPR" 10 "optimized" } } */
    ++/* { dg-final { scan-tree-dump-times "MAX_EXPR" 10 "optimized" } } */
     
      ## gcc/testsuite/gcc.dg/tree-ssa/pr125700.c (new) ##
     @@
    @@ gcc/testsuite/gcc.dg/tree-ssa/pr125700.c (new)
     +/* { dg-do compile } */
     +/* { dg-options "-O1 -fdump-tree-optimized" } */
     +
    ++/* Base test cases.  */
     +unsigned
     +fumin (unsigned x, unsigned y)
     +{
    @@ gcc/testsuite/gcc.dg/tree-ssa/pr125700.c (new)
     +  return x > y ? x : y;
     +}
     +
    ++/* Conditional operator variants.  */
     +unsigned
     +fumin_ne (unsigned x, unsigned y)
     +{
    @@ gcc/testsuite/gcc.dg/tree-ssa/pr125700.c (new)
     +  return x > y ? x : y;
     +}
     +
    ++/* Commutativity tests for min/max operator.  */
     +unsigned
     +fumin_flip (unsigned x, unsigned y)
     +{
    @@ gcc/testsuite/gcc.dg/tree-ssa/pr125700.c (new)
     +
     +/* The if and all conditional operators should be removed
     +   from the optimized dump output.  */
    -+/* { dg-final { scan-tree-dump-not "if" "optimized" } } */
    ++/* { dg-final { scan-tree-dump-not {if \(} "optimized" } } */
     +/* { dg-final { scan-tree-dump-not " == " "optimized" } } */
     +/* { dg-final { scan-tree-dump-not " != " "optimized" } } */
     +/* { dg-final { scan-tree-dump-not " <= " "optimized" } } */
-- 
2.54.0

Reply via email to