This should have been done a while ago.

The call to simplify MIN and MAX was guarded by a check for INTEGRAL, so I removed that as the code was already generalized to work with any type.

And no attempt was being made to pass in a relation... so I query for a relation between op0 and op1, and pass it to fold_range. And then all the right things happen.

I see Jeff fixed PR 110199 in DOM.   I copied the tests from that and created the same tests to test that
  a) EVRP is removing all the MIN_EXPR and MAX_EXPRs
  b) Added a float version of the tests with -ffast-math  to show its also working with floats.

Bootstraps on x86_64-pc-linux-gnu with no regressions.  OK for trunk?

Andrew

PS.    The same patch will not work on gcc-14, but the code could be ported if we wanted to.  Presumably DOM is getting the integral versions, so it would only be floats we would be new to handling.

gcc-13 is more challenging, but I think the infrastructure is there for the integer version. I dont think we have the proper float support yet.   But if DOM is already doing it from Jeffs patch, I'm not sure it matters.

From fd4a9e3a3a9ab8cc4c728a0e64463755ccf39ed8 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacl...@redhat.com>
Date: Fri, 10 Jan 2025 13:33:01 -0500
Subject: [PATCH] Use relations when simplifying MIN and MAX.

Query for known relations between the operands, and pass that to
fold_range to help simplify MIN and MAX relations.
Make it type agnostic as well.

Adapt testcases from DOM to EVRP (e suffix) and test floats (f suffix).

	PR tree-optimization/88575
	gcc/
	* vr-values.cc (simplify_using_ranges::fold_cond_with_ops): Query
	relation between op0 and op1 and utilize it.
	(simplify_using_ranges::simplify): Do not eliminate float checks.

	gcc/testsuite/
	gcc.dg/tree-ssa/minmax-27.c: Disable VRP.
	gcc.dg/tree-ssa/minmax-27e.c: New.
	gcc.dg/tree-ssa/minmax-27f.c: New.
	gcc.dg/tree-ssa/minmax-28.c: Disable VRP.
	gcc.dg/tree-ssa/minmax-28e.c: New.
	gcc.dg/tree-ssa/minmax-2fe.c: New.
---
 gcc/testsuite/gcc.dg/tree-ssa/minmax-27.c  |   2 +-
 gcc/testsuite/gcc.dg/tree-ssa/minmax-27e.c | 118 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/minmax-27f.c | 118 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/minmax-28.c  |   2 +-
 gcc/testsuite/gcc.dg/tree-ssa/minmax-28e.c | 117 ++++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/minmax-28f.c | 117 ++++++++++++++++++++
 gcc/vr-values.cc                           |  13 ++-
 7 files changed, 481 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/minmax-27e.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/minmax-27f.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/minmax-28e.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/minmax-28f.c

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-27.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-27.c
index 4b94203b0d0..a99af6eb521 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/minmax-27.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-27.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-dom2" } */
+/* { dg-options "-O2 -fdump-tree-dom2 -fno-tree-vrp" } */
 
 
 int min1(int a, int b)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-27e.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-27e.c
new file mode 100644
index 00000000000..8498ffd2017
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-27e.c
@@ -0,0 +1,118 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+
+int min1(int a, int b)
+{
+    if (a <= b)
+        return a < b ? a : b;
+    return 0;
+}
+
+int min2(int a, int b)
+{
+    if (a <= b)
+        return a > b ? b : a;
+    return 0;
+}
+
+int min3(int a, int b)
+{
+    if (a < b)
+        return a < b ? a : b;
+    return 0;
+}
+
+int min4(int a, int b)
+{
+    if (a < b)
+        return a > b ? b : a;
+    return 0;
+}
+
+int min5(int a, int b)
+{
+    if (a <= b)
+        return a <= b ? a : b;
+    return 0;
+}
+
+int min6(int a, int b)
+{
+    if (a <= b)
+        return a >= b ? b : a;
+    return 0;
+}
+
+int min7(int a, int b)
+{
+    if (a < b)
+        return a <= b ? a : b;
+    return 0;
+}
+
+int min8(int a, int b)
+{
+    if (b > a)
+        return a >= b ? b : a;
+    return 0;
+}
+
+int min9(int a, int b)
+{
+    if (b >= a)
+        return a < b ? a : b;
+    return 0;
+}
+
+int min10(int a, int b)
+{
+    if (b >= a)
+        return a > b ? b : a;
+    return 0;
+}
+
+int min11(int a, int b)
+{
+    if (b > a)
+        return a < b ? a : b;
+    return 0;
+}
+
+int min12(int a, int b)
+{
+    if (b > a)
+        return a > b ? b : a;
+    return 0;
+}
+
+int min13(int a, int b)
+{
+    if (b >= a)
+        return a <= b ? a : b;
+    return 0;
+}
+
+int min14(int a, int b)
+{
+    if (b >= a)
+        return a >= b ? b : a;
+    return 0;
+}
+
+int min15(int a, int b)
+{
+    if (b > a)
+        return a <= b ? a : b;
+    return 0;
+}
+
+int min16(int a, int b)
+{
+    if (b > a)
+        return a >= b ? b : a;
+    return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "MIN_EXPR" "evrp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-27f.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-27f.c
new file mode 100644
index 00000000000..63398d4495f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-27f.c
@@ -0,0 +1,118 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffast-math -fdump-tree-evrp" } */
+
+
+float min1(float a, float b)
+{
+    if (a <= b)
+        return a < b ? a : b;
+    return 0.0;
+}
+
+float min2(float a, float b)
+{
+    if (a <= b)
+        return a > b ? b : a;
+    return 0.0;
+}
+
+float min3(float a, float b)
+{
+    if (a < b)
+        return a < b ? a : b;
+    return 0.0;
+}
+
+float min4(float a, float b)
+{
+    if (a < b)
+        return a > b ? b : a;
+    return 0.0;
+}
+
+float min5(float a, float b)
+{
+    if (a <= b)
+        return a <= b ? a : b;
+    return 0.0;
+}
+
+float min6(float a, float b)
+{
+    if (a <= b)
+        return a >= b ? b : a;
+    return 0.0;
+}
+
+float min7(float a, float b)
+{
+    if (a < b)
+        return a <= b ? a : b;
+    return 0.0;
+}
+
+float min8(float a, float b)
+{
+    if (b > a)
+        return a >= b ? b : a;
+    return 0.0;
+}
+
+float min9(float a, float b)
+{
+    if (b >= a)
+        return a < b ? a : b;
+    return 0.0;
+}
+
+float min10(float a, float b)
+{
+    if (b >= a)
+        return a > b ? b : a;
+    return 0.0;
+}
+
+float min11(float a, float b)
+{
+    if (b > a)
+        return a < b ? a : b;
+    return 0.0;
+}
+
+float min12(float a, float b)
+{
+    if (b > a)
+        return a > b ? b : a;
+    return 0.0;
+}
+
+float min13(float a, float b)
+{
+    if (b >= a)
+        return a <= b ? a : b;
+    return 0.0;
+}
+
+float min14(float a, float b)
+{
+    if (b >= a)
+        return a >= b ? b : a;
+    return 0.0;
+}
+
+float min15(float a, float b)
+{
+    if (b > a)
+        return a <= b ? a : b;
+    return 0.0;
+}
+
+float min16(float a, float b)
+{
+    if (b > a)
+        return a >= b ? b : a;
+    return 0.0;
+}
+
+/* { dg-final { scan-tree-dump-not "MIN_EXPR" "evrp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-28.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-28.c
index 732126d7449..aa5598a292f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/minmax-28.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-28.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-dom2" } */
+/* { dg-options "-O2 -fdump-tree-dom2 -fno-tree-vrp" } */
 
 int max1(int a, int b)
 {
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-28e.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-28e.c
new file mode 100644
index 00000000000..5d11f2d72f6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-28e.c
@@ -0,0 +1,117 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+int max1(int a, int b)
+{
+    if (a <= b)
+        return a < b ? b : a;
+    return 0;
+}
+
+int max2(int a, int b)
+{
+    if (a <= b)
+        return a > b ? a : b;
+    return 0;
+}
+
+int max3(int a, int b)
+{
+    if (a < b)
+        return a < b ? b : a;
+    return 0;
+}
+
+int max4(int a, int b)
+{
+    if (a < b)
+        return a > b ? a : b;
+    return 0;
+}
+
+int max5(int a, int b)
+{
+    if (a <= b)
+        return a <= b ? b : a;
+    return 0;
+}
+
+int max6(int a, int b)
+{
+    if (a <= b)
+        return a >= b ? a : b;
+    return 0;
+}
+
+int max7(int a, int b)
+{
+    if (a < b)
+        return a <= b ? b : a;
+    return 0;
+}
+
+int max8(int a, int b)
+{
+    if (b > a)
+        return a >= b ? a : b;
+    return 0;
+}
+
+int max9(int a, int b)
+{
+    if (b >= a)
+        return a < b ? b : a;
+    return 0;
+}
+
+int max10(int a, int b)
+{
+    if (b >= a)
+        return a > b ? a : b;
+    return 0;
+}
+
+int max11(int a, int b)
+{
+    if (b > a)
+        return a < b ? b : a;
+    return 0;
+}
+
+int max12(int a, int b)
+{
+    if (b > a)
+        return a > b ? a : b;
+    return 0;
+}
+
+int max13(int a, int b)
+{
+    if (b >= a)
+        return a <= b ? b : a;
+    return 0;
+}
+
+int max14(int a, int b)
+{
+    if (b >= a)
+        return a >= b ? a : b;
+    return 0;
+}
+
+int max15(int a, int b)
+{
+    if (b > a)
+        return a <= b ? b : a;
+    return 0;
+}
+
+int max16(int a, int b)
+{
+    if (b > a)
+        return a >= b ? a : b;
+    return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "MAX_EXPR" "evrp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-28f.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-28f.c
new file mode 100644
index 00000000000..f37d3c39468
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/minmax-28f.c
@@ -0,0 +1,117 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffast-math -fdump-tree-evrp" } */
+
+float max1(float a, float b)
+{
+    if (a <= b)
+        return a < b ? b : a;
+    return 0.0;
+}
+
+float max2(float a, float b)
+{
+    if (a <= b)
+        return a > b ? a : b;
+    return 0.0;
+}
+
+float max3(float a, float b)
+{
+    if (a < b)
+        return a < b ? b : a;
+    return 0.0;
+}
+
+float max4(float a, float b)
+{
+    if (a < b)
+        return a > b ? a : b;
+    return 0.0;
+}
+
+float max5(float a, float b)
+{
+    if (a <= b)
+        return a <= b ? b : a;
+    return 0.0;
+}
+
+float max6(float a, float b)
+{
+    if (a <= b)
+        return a >= b ? a : b;
+    return 0.0;
+}
+
+float max7(float a, float b)
+{
+    if (a < b)
+        return a <= b ? b : a;
+    return 0.0;
+}
+
+float max8(float a, float b)
+{
+    if (b > a)
+        return a >= b ? a : b;
+    return 0.0;
+}
+
+float max9(float a, float b)
+{
+    if (b >= a)
+        return a < b ? b : a;
+    return 0.0;
+}
+
+float max10(float a, float b)
+{
+    if (b >= a)
+        return a > b ? a : b;
+    return 0.0;
+}
+
+float max11(float a, float b)
+{
+    if (b > a)
+        return a < b ? b : a;
+    return 0.0;
+}
+
+float max12(float a, float b)
+{
+    if (b > a)
+        return a > b ? a : b;
+    return 0.0;
+}
+
+float max13(float a, float b)
+{
+    if (b >= a)
+        return a <= b ? b : a;
+    return 0.0;
+}
+
+float max14(float a, float b)
+{
+    if (b >= a)
+        return a >= b ? a : b;
+    return 0.0;
+}
+
+float max15(float a, float b)
+{
+    if (b > a)
+        return a <= b ? b : a;
+    return 0.0;
+}
+
+float max16(float a, float b)
+{
+    if (b > a)
+        return a >= b ? a : b;
+    return 0.0;
+}
+
+/* { dg-final { scan-tree-dump-not "MAX_EXPR" "evrp" } } */
+
diff --git a/gcc/vr-values.cc b/gcc/vr-values.cc
index 18e8e5865db..ed590138fe8 100644
--- a/gcc/vr-values.cc
+++ b/gcc/vr-values.cc
@@ -318,7 +318,14 @@ simplify_using_ranges::fold_cond_with_ops (enum tree_code code,
 
   int_range<1> res;
   range_op_handler handler (code);
-  if (handler && handler.fold_range (res, boolean_type_node, r0, r1))
+
+  // Find any relation between op0 and op1 and pass it to fold_range.
+  relation_kind rel = VREL_VARYING;
+  if (gimple_range_ssa_p (op0) && gimple_range_ssa_p (op1))
+    rel = query->relation ().query (s, op0, op1);
+
+  if (handler && handler.fold_range (res, boolean_type_node, r0, r1,
+				     relation_trio::op1_op2 (rel)))
     {
       if (res == range_true ())
 	return boolean_true_node;
@@ -1977,9 +1984,7 @@ simplify_using_ranges::simplify (gimple_stmt_iterator *gsi)
 
 	case MIN_EXPR:
 	case MAX_EXPR:
-	  if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
-	    return simplify_min_or_max_using_ranges (gsi, stmt);
-	  break;
+	  return simplify_min_or_max_using_ranges (gsi, stmt);
 
 	case RSHIFT_EXPR:
 	  {
-- 
2.45.0

Reply via email to