[3/3] MATCH: Add some more value_replacement simplifications to match

Message ID 20231029164049.994454-4-pinskia@gmail.com
State Unresolved
Headers
Series start of moving value replacement from phiopt to match |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Andrew Pinski Oct. 29, 2023, 4:40 p.m. UTC
  This moves a few more value_replacements simplifications to match.
/* a == 1 ? b : a * b -> a * b */
/* a == 1 ? b : b / a  -> b / a */
/* a == -1 ? b : a & b -> a & b */

Also adds a testcase to show can we catch these where value_replacement would not
(but other passes would).

Bootstrapped and tested on x86_64-linux-gnu with no regressions.

gcc/ChangeLog:

	* match.pd (`a == 1 ? b : a OP b`): New pattern.
	(`a == -1 ? b : a & b`): New pattern.

gcc/testsuite/ChangeLog:

	* gcc.dg/tree-ssa/phi-opt-value-4.c: New test.
---
 gcc/match.pd                                  | 18 ++++++++++
 .../gcc.dg/tree-ssa/phi-opt-value-4.c         | 36 +++++++++++++++++++
 2 files changed, 54 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c
  

Comments

Richard Biener Oct. 30, 2023, 9:30 a.m. UTC | #1
On Sun, Oct 29, 2023 at 5:41 PM Andrew Pinski <pinskia@gmail.com> wrote:
>
> This moves a few more value_replacements simplifications to match.
> /* a == 1 ? b : a * b -> a * b */
> /* a == 1 ? b : b / a  -> b / a */
> /* a == -1 ? b : a & b -> a & b */
>
> Also adds a testcase to show can we catch these where value_replacement would not
> (but other passes would).
>
> Bootstrapped and tested on x86_64-linux-gnu with no regressions.

OK.

> gcc/ChangeLog:
>
>         * match.pd (`a == 1 ? b : a OP b`): New pattern.
>         (`a == -1 ? b : a & b`): New pattern.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.dg/tree-ssa/phi-opt-value-4.c: New test.
> ---
>  gcc/match.pd                                  | 18 ++++++++++
>  .../gcc.dg/tree-ssa/phi-opt-value-4.c         | 36 +++++++++++++++++++
>  2 files changed, 54 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c
>
> diff --git a/gcc/match.pd b/gcc/match.pd
> index 9bc945ccada..6efa97cc6ae 100644
> --- a/gcc/match.pd
> +++ b/gcc/match.pd
> @@ -4159,6 +4159,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
>    (cond (eq @0 integer_zerop) @1 (op@2 @1 @0))
>     @2))
>
> +/* a == 1 ? b : b / a  -> b / a */
> +(for op (trunc_div ceil_div floor_div round_div exact_div)
> + (simplify
> +  (cond (eq @0 integer_onep) @1 (op@2 @1 @0))
> +   @2))
> +
> +/* a == 1 ? b : a * b -> a * b */
> +(for op (mult)
> + (simplify
> +  (cond (eq @0 integer_onep) @1 (op:c@2 @1 @0))
> +   @2))
> +
> +/* a == -1 ? b : a & b -> a & b */
> +(for op (bit_and)
> + (simplify
> +  (cond (eq @0 integer_all_onesp) @1 (op:c@2 @1 @0))
> +   @2))
> +
>  /* PTR == 0 ? 0 : &PTR->field -> PTR if field offset was 0. */
>  (simplify
>   (cond (eq @0 integer_zerop) integer_zerop ADDR_EXPR@1)
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c
> new file mode 100644
> index 00000000000..380082cb463
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c
> @@ -0,0 +1,36 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O1 -fdump-tree-fre3 -fdump-tree-phiopt1 -fdump-tree-optimized" } */
> +
> +[[gnu::const]]
> +int constcall(int);
> +
> +int fdiv(int a, int b)
> +{
> +  int c = b/a;
> +  int t = constcall(c);
> +  int d;
> +  if (a == 1) d = b; else d = c;
> +  return constcall(d) + t;
> +}
> +int fmult(int a, int b)
> +{
> +  int c = b*a;
> +  int t = constcall(c);
> +  int d;
> +  if (a == 1) d = b; else d = c;
> +  return constcall(d) + t;
> +}
> +int fand(int a, int b)
> +{
> +  int c = b&a;
> +  int t = constcall(c);
> +  int d;
> +  if (a == -1) d = b; else d = c;
> +  return constcall(d) + t;
> +}
> +
> +/* Should be able to optimize away the if statements in phiopt1. */
> +/* { dg-final { scan-tree-dump-not "if " "phiopt1" } } */
> +/* fre3 should be optimize each function to just `return constcall(a OP b) * 2;`. */
> +/* { dg-final { scan-tree-dump-times "constcall " 3 "fre3" } } */
> +/* { dg-final { scan-tree-dump-times "constcall " 3 "optimized" } } */
> --
> 2.39.3
>
  

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index 9bc945ccada..6efa97cc6ae 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -4159,6 +4159,24 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (cond (eq @0 integer_zerop) @1 (op@2 @1 @0))
    @2))
 
+/* a == 1 ? b : b / a  -> b / a */
+(for op (trunc_div ceil_div floor_div round_div exact_div)
+ (simplify
+  (cond (eq @0 integer_onep) @1 (op@2 @1 @0))
+   @2))
+
+/* a == 1 ? b : a * b -> a * b */
+(for op (mult)
+ (simplify
+  (cond (eq @0 integer_onep) @1 (op:c@2 @1 @0))
+   @2))
+
+/* a == -1 ? b : a & b -> a & b */
+(for op (bit_and)
+ (simplify
+  (cond (eq @0 integer_all_onesp) @1 (op:c@2 @1 @0))
+   @2))
+
 /* PTR == 0 ? 0 : &PTR->field -> PTR if field offset was 0. */
 (simplify
  (cond (eq @0 integer_zerop) integer_zerop ADDR_EXPR@1)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c
new file mode 100644
index 00000000000..380082cb463
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-value-4.c
@@ -0,0 +1,36 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-fre3 -fdump-tree-phiopt1 -fdump-tree-optimized" } */
+
+[[gnu::const]]
+int constcall(int);
+
+int fdiv(int a, int b)
+{
+  int c = b/a;
+  int t = constcall(c);
+  int d;
+  if (a == 1) d = b; else d = c;
+  return constcall(d) + t;
+}
+int fmult(int a, int b)
+{
+  int c = b*a;
+  int t = constcall(c);
+  int d;
+  if (a == 1) d = b; else d = c;
+  return constcall(d) + t;
+}
+int fand(int a, int b)
+{
+  int c = b&a;
+  int t = constcall(c);
+  int d;
+  if (a == -1) d = b; else d = c;
+  return constcall(d) + t;
+}
+
+/* Should be able to optimize away the if statements in phiopt1. */
+/* { dg-final { scan-tree-dump-not "if " "phiopt1" } } */
+/* fre3 should be optimize each function to just `return constcall(a OP b) * 2;`. */
+/* { dg-final { scan-tree-dump-times "constcall " 3 "fre3" } } */
+/* { dg-final { scan-tree-dump-times "constcall " 3 "optimized" } } */