diff mbox series

[v2] MATCH: Simplify `min(a, b) op max(a, b)` to `a op b` [PR109401]

Message ID 20241111115545.31217-1-quic_eikagupt@quicinc.com
State New
Headers show
Series [v2] MATCH: Simplify `min(a, b) op max(a, b)` to `a op b` [PR109401] | expand

Commit Message

Eikansh Gupta Nov. 11, 2024, 11:55 a.m. UTC
This patch simplify `min(a,b) op max(a,b)` to `a op b`. This optimization
will work for all the binary commutative operations. So, the `op` here can
be one of {plus, mult, bit_and, bit_xor, bit_ior, eq, ne, min, max}.

	PR tree-optimization/109878
	PR 109401

gcc/ChangeLog:

	* match.pd (min(a,b) op max(a,b) -> a op b): New pattern.

gcc/testsuite/ChangeLog:

	* gcc.dg/tree-ssa/pr109401.c: New test.
        * gcc.dg/tree-ssa/pr109401-1.c: New test.

Signed-off-by: Eikansh Gupta <quic_eikagupt@quicinc.com>
---
 gcc/match.pd                               |  7 +++
 gcc/testsuite/gcc.dg/tree-ssa/pr109401-1.c | 35 +++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr109401.c   | 61 ++++++++++++++++++++++
 3 files changed, 103 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr109401-1.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr109401.c

Comments

Jeff Law Nov. 11, 2024, 7:25 p.m. UTC | #1
On 11/11/24 4:55 AM, Eikansh Gupta wrote:
> This patch simplify `min(a,b) op max(a,b)` to `a op b`. This optimization
> will work for all the binary commutative operations. So, the `op` here can
> be one of {plus, mult, bit_and, bit_xor, bit_ior, eq, ne, min, max}.
> 
> 	PR tree-optimization/109878
> 	PR 109401
> 
> gcc/ChangeLog:
> 
> 	* match.pd (min(a,b) op max(a,b) -> a op b): New pattern.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.dg/tree-ssa/pr109401.c: New test.
>          * gcc.dg/tree-ssa/pr109401-1.c: New test.
It seems to me this ought to work when the min/max reversed as well, or 
am I missing something?

jeff
Eikansh Gupta Nov. 12, 2024, 4:32 a.m. UTC | #2
Hi,

>          It seems to me this ought to work when the min/max reversed as well, or
>    am I missing something?

Yes, it should work when min/max are reversed.

Regards,
Eikansh
Jeff Law Nov. 15, 2024, 1:22 a.m. UTC | #3
On 11/11/24 9:32 PM, Eikansh Gupta wrote:
> Hi,
> 
>  >          It seems to me this ought to work when the min/max reversed 
> as well, or
>  >    am I missing something?
> 
> Yes, it should work when min/max are reversed.
So are you going to add support for both?  Seems to me like we'd want to 
support both orders.

jeff
Andrew Pinski Nov. 15, 2024, 1:33 a.m. UTC | #4
On Thu, Nov 14, 2024 at 5:30 PM Jeff Law <jeffreyalaw@gmail.com> wrote:
>
>
>
> On 11/11/24 9:32 PM, Eikansh Gupta wrote:
> > Hi,
> >
> >  >          It seems to me this ought to work when the min/max reversed
> > as well, or
> >  >    am I missing something?
> >
> > Yes, it should work when min/max are reversed.
> So are you going to add support for both?  Seems to me like we'd want to
> support both orders.

Both orders are already supported:
+  (op:c (min:c @0 @1) (max @0 @1))

Notice the `:c` on op. It means both `(plus (min @0 @1)  (max @0 @1)
)` and `(plus (max @0 @1)  (min @0 @1) )` will match. Unless I am
misunderstanding something here too.

Thanks,
Andrew Pinski

>
> jeff
>
Eikansh Gupta Nov. 15, 2024, 12:16 p.m. UTC | #5
Hi Jeff,

The patch has support for both. In the test cases, approx half the test cases have min(a, b) op max(a, b) and the other half have max(a, b) op min(a, b).

Regards,
Eikansh
Jeff Law Nov. 16, 2024, 6:48 p.m. UTC | #6
On 11/15/24 5:16 AM, Eikansh Gupta wrote:
> Hi Jeff,
> 
> The patch has support for both. In the test cases, approx half the test 
> cases have |min(a, b) op max(a, b)| and the other half have |max(a, b) 
> op min(a, b). |
For some reason my brain just doesn't parse match.pd code well.

OK for the trunk.

jeff
Andrew Pinski Nov. 16, 2024, 7:12 p.m. UTC | #7
On Sat, Nov 16, 2024 at 10:48 AM Jeff Law <jeffreyalaw@gmail.com> wrote:
>
>
>
>
> On 11/15/24 5:16 AM, Eikansh Gupta wrote:
> > Hi Jeff,
> >
> > The patch has support for both. In the test cases, approx half the test
> > cases have |min(a, b) op max(a, b)| and the other half have |max(a, b)
> > op min(a, b). |
> For some reason my brain just doesn't parse match.pd code well.
>
> OK for the trunk.

Pushed as r15-5355 with small changes to the commit message dealing
with the format in the changelog.

Thanks,
Andrew

>
> jeff
>
diff mbox series

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index 00988241348..bbc7d708f32 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4660,6 +4660,13 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
     @0
     @2)))
 
+/* min (a, b) op max (a, b) -> a op b */
+(for op (plus mult bit_and bit_xor bit_ior eq ne min max)
+ (simplify
+  (op:c (min:c @0 @1) (max @0 @1))
+   (if (!HONOR_NANS (@0))
+    (op @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/pr109401-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr109401-1.c
new file mode 100644
index 00000000000..3f72516c293
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr109401-1.c
@@ -0,0 +1,35 @@ 
+/* PR tree-optimization/109878 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+/* Returns max (a, b) */
+int max(int a, int b) {
+  if (b > a)
+    return b;
+  else
+    return a;
+}
+
+/* Returns min (a, b) */
+int min(int a, int b) {
+  if (b < a)
+    return b;
+  else
+    return a;
+}
+
+/* These functions should return a op b */
+int f8(int a, int b)
+{
+  return min (max (a, b), min (a, b));
+}
+
+int f9(int a, int b)
+{
+  return max (min (a, b), max (a, b));
+}
+
+/* Function min and f8 should have MIN_EXPR */
+/* Function max and f9 should have MAX_EXPR */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 2 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr109401.c b/gcc/testsuite/gcc.dg/tree-ssa/pr109401.c
new file mode 100644
index 00000000000..11177d97fbf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr109401.c
@@ -0,0 +1,61 @@ 
+/* PR tree-optimization/109878 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-optimized" } */
+
+/* Returns max (a, b) */
+int max(int a, int b) {
+  if (b > a)
+    return b;
+  else
+    return a;
+}
+
+/* Returns min (a, b) */
+int min(int a, int b) {
+  if (b < a)
+    return b;
+  else
+    return a;
+}
+
+/* All the functions here shouldn't evalute min or max of a and b
+ * These functions should return a op b */
+int f(int a, int b)
+{
+  return max (a, b) + min (a, b);
+}
+
+int f1(int a, int b)
+{
+  return max (a, b) * min (a, b);
+}
+
+int f2(int a, int b)
+{
+  return max (a, b) | min (a, b);
+}
+
+int f3(int a, int b)
+{
+  return max (a, b) & min (a, b);
+}
+
+int f5(int a, int b)
+{
+  return min (a, b) ^ max (a, b);
+}
+
+int f6(int a, int b)
+{
+  return min (a, b) == max (a, b);
+}
+
+int f7(int a, int b)
+{
+  return min (a, b) != max (a, b);
+}
+
+/* Function min should have MIN_EXPR */
+/* Function max should have MAX_EXPR */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 1 "optimized" } } */