The following patterns and their variants are added.
min(a,b) {<=,>,<,>=} max(a,b) -> {true,false,a!=b,a==b}
Bootstrapped and tested on x86_64-linux-gnu and aarch64-linux-gnu.
PR tree-optimization/113379
gcc/ChangeLog:
* match.pd (min(a,b) {<=,>,<,>=} max(a,b)): New patterns.
gcc/testsuite/ChangeLog:
* gcc.dg/tree-ssa/pr113379.c: New test.
Signed-off-by: Pengxuan Zheng <[email protected]>
---
gcc/match.pd | 21 ++++++++
gcc/testsuite/gcc.dg/tree-ssa/pr113379.c | 69 ++++++++++++++++++++++++
2 files changed, 90 insertions(+)
create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr113379.c
diff --git a/gcc/match.pd b/gcc/match.pd
index 7b652afb43d..89580a858c5 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4995,6 +4995,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (!HONOR_NANS (@0))
(op @0 @1))))
+/* min (a, b) <= max (a, b) -> true
+ max (a, b) >= min (a, b) -> true
+ min (a, b) > max (a, b) -> false
+ max (a, b) < min (a, b) -> false */
+(for legt (le gt)
+ (simplify
+ (legt:c (min:c @0 @1) (max @0 @1))
+ (if (!HONOR_NANS (@0))
+ { constant_boolean_node (legt == LE_EXPR, type); })))
+
+/* min (a, b) < max (a, b) -> a != b
+ max (a, b) > min (a, b) -> a != b
+ min (a, b) >= max (a, b) -> a == b
+ max (a, b) <= min (a, b) -> a == b */
+(for ltge (lt ge)
+ neeq (ne eq)
+ (simplify
+ (ltge:c (min:c @0 @1) (max @0 @1))
+ (if (!HONOR_NANS (@0))
+ (neeq @0 @1))))
+
/* Simplify min (&var[off0], &var[off1]) etc. depending on whether
the addresses are known to be less, equal or greater. */
(for minmax (min max)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr113379.c
b/gcc/testsuite/gcc.dg/tree-ssa/pr113379.c
new file mode 100644
index 00000000000..5a34d919acf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr113379.c
@@ -0,0 +1,69 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+int
+f1 (int a, int b)
+{
+ int min = a < b ? a : b;
+ int max = a > b ? a : b;
+ return min <= max;
+}
+
+int
+f2 (int a, int b)
+{
+ int min = a < b ? a : b;
+ int max = a > b ? a : b;
+ return min > max;
+}
+
+int
+f3 (int a, int b)
+{
+ int max = a > b ? a : b;
+ int min = a < b ? a : b;
+ return max >= min;
+}
+
+int
+f4 (int a, int b)
+{
+ int max = a > b ? a : b;
+ int min = a < b ? a : b;
+ return max < min;
+}
+
+int
+f5 (int a, int b)
+{
+ int min = a < b ? a : b;
+ int max = a > b ? a : b;
+ return min < max;
+}
+
+int
+f6 (int a, int b)
+{
+ int min = a < b ? a : b;
+ int max = a > b ? a : b;
+ return min >= max;
+}
+
+int
+f7 (int a, int b)
+{
+ int max = a > b ? a : b;
+ int min = a < b ? a : b;
+ return max > min;
+}
+
+int
+f8 (int a, int b)
+{
+ int max = a > b ? a : b;
+ int min = a < b ? a : b;
+ return max <= min;
+}
+
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 0 "optimized" } } */
--
2.34.1