]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
match: Add MIN<a,b> {<=,>,<,>=} MAX<a,b> simplifications [PR113379]
authorPengxuan Zheng <pengxuan.zheng@oss.qualcomm.com>
Thu, 26 Mar 2026 18:42:57 +0000 (11:42 -0700)
committerPengxuan Zheng <pengxuan.zheng@oss.qualcomm.com>
Wed, 29 Apr 2026 20:16:53 +0000 (13:16 -0700)
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 <pengxuan.zheng@oss.qualcomm.com>
gcc/match.pd
gcc/testsuite/gcc.dg/tree-ssa/pr113379.c [new file with mode: 0644]

index 65a2292ecae3944468a8371b4ace5116912857f4..df960a0cf29ffc4b6bfe64af583597c3a750b1be 100644 (file)
@@ -5012,6 +5012,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 @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 @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 (file)
index 0000000..684fbd2
--- /dev/null
@@ -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-not "MIN_EXPR" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "MAX_EXPR" "optimized" } } */