https://gcc.gnu.org/g:b0eeb540497c7b9dee01f8724f9a4978b53a12ae
commit r15-6815-gb0eeb540497c7b9dee01f8724f9a4978b53a12ae Author: Andrew MacLeod <amacl...@redhat.com> Date: Fri Jan 10 13:33:01 2025 -0500 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-28f.c: New. Diff: --- 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(-) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/minmax-27.c b/gcc/testsuite/gcc.dg/tree-ssa/minmax-27.c index 4b94203b0d05..a99af6eb521e 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 000000000000..8498ffd20173 --- /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 000000000000..63398d4495f0 --- /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 732126d74494..aa5598a292f7 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 000000000000..5d11f2d72f6d --- /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 000000000000..f37d3c39468b --- /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 18e8e5865dbf..ed590138fe8f 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: {