[v2] gimple-match.pd Add more optimization for gimple_cond

Message ID 20231128025527.36740-1-wangfeng@eswincomputing.com
State Accepted
Headers
Series [v2] gimple-match.pd Add more optimization for gimple_cond |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Feng Wang Nov. 28, 2023, 2:55 a.m. UTC
  The link of PATCH v1: https://www.mail-archive.com/gcc-patches@gcc.gnu.org/msg326661.html
This patch add another condition for gimple-cond optimization. Refer to
the following test case.
int foo1 (int data, int res)
{
  res = data & 0xf;
  res |= res << 4;
  if (res < 0x22)
    return 0x22;
  return res;
}
with the compilation flag "-O2",
before this patch the log info of phiopt2 pass is
  <bb 2> [local count: 1073741824]:
  res_5 = data_1(D) & 15;
  _6 = (unsigned int) res_5;
  _7 = _6 * 17;
  res_8 = (int) _7;
  if (_7 <= 33)
    goto <bb 3>; [21.72%]
  else
    goto <bb 4>; [78.28%]

  <bb 3> [local count: 233216728]:

  <bb 4> [local count: 1073741824]:
  # _9 = PHI <res_8(2), 34(3)>
  return _9;
after this patch the the log info of phiopt2 pass is
  <bb 2> [local count: 1073741824]:
  res_5 = data_1(D) & 15;
  _6 = (unsigned int) res_5;
  _7 = _6 * 17;
  res_8 = (int) _7;
  _10 = MAX_EXPR <_7, 34>;
  _3 = (int) _10;
  return _3;
This patch optimizes the phi node to generate "MAX_EXPR".
The root cause of minmax replacement failure is the type of "_7"
is unsigned, but the type of const_int "34" is signed. It makes
types_match (c2_type, from_type) return false. So I add another
condition to process this scenario.

gcc/ChangeLog:

        * match.pd: Add another condition to process type mismatch.

gcc/testsuite/ChangeLog:

        * gcc.dg/tree-ssa/phi-opt-41.c: New test.
---
 gcc/match.pd                               |  5 ++++-
 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-41.c | 24 ++++++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/phi-opt-41.c
  

Patch

diff --git a/gcc/match.pd b/gcc/match.pd
index 95225e4ca5f..e864845bfa9 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -5419,7 +5419,10 @@  DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	 && (types_match (c2_type, from_type)
 	     || (TYPE_PRECISION (c2_type) > TYPE_PRECISION (from_type)
 		 && (TYPE_UNSIGNED (from_type)
-		     || TYPE_SIGN (c2_type) == TYPE_SIGN (from_type)))))
+		     || TYPE_SIGN (c2_type) == TYPE_SIGN (from_type)))
+             || (TYPE_UNSIGNED (from_type) != TYPE_UNSIGNED (c2_type)
+                 && TYPE_PRECISION (c2_type) == TYPE_PRECISION (from_type)
+                 && !TYPE_OVERFLOW_WRAPS (c2_type))))
        {
 	 if (cmp != EQ_EXPR)
 	   code = minmax_from_comparison (cmp, @1, @3, @1, @2);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-41.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-41.c
new file mode 100644
index 00000000000..d1101c2f9f7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-41.c
@@ -0,0 +1,24 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-phiopt2" } */
+
+int foo1 (int data, int res)
+{
+  res = data & 0xf;
+  res |= res << 4;
+  if (res < 0x22)
+    return 0x22;
+  return res;
+}
+
+int foo2 (int data, int res)
+{
+  res = data & 0xf;
+  unsigned int r = res;
+  r*=17;
+  res = r;
+  if (r < 0x22)
+    return 0x22;
+  return res;
+}
+
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 2 "phiopt2" } } */
\ No newline at end of file