From: Pan Li <pan2...@intel.com>

For mul_overflow api, we will have PHI node similar as below:

  _6 = .MUL_OVERFLOW (a_4(D), b_5(D));
  _2 = IMAGPART_EXPR <_6>;
  if (_2 != 0)
    goto <bb 4>; [35.00%]
  else
    goto <bb 3>; [65.00%]

  <bb 3> [local count: 697932184]:
  _1 = REALPART_EXPR <_6>;

  <bb 4> [local count: 1073741824]:
  # _3 = PHI <18446744073709551615(2), _1(3)>

Based on the help of match.pd pattern match, the widening-mul will
try to convert it to below:

  _3 = .SAT_MUL (a_4(D), b_5(D));

gcc/ChangeLog:

        * tree-ssa-math-opts.cc (match_saturation_mul): Add new func
        to emit IFN_SAT_MUL if matched.
        (math_opts_dom_walker::after_dom_children): Try to match
        the phi node for SAT_MUL.

Signed-off-by: Pan Li <pan2...@intel.com>
---
 gcc/tree-ssa-math-opts.cc | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
index ca98205d58f..591ecd387a6 100644
--- a/gcc/tree-ssa-math-opts.cc
+++ b/gcc/tree-ssa-math-opts.cc
@@ -4241,6 +4241,39 @@ match_unsigned_saturation_mul (gimple_stmt_iterator 
*gsi, gassign *stmt)
                                                    ops[0], ops[1]);
 }
 
+/* Try to match saturation unsigned mul, aka:
+     _6 = .MUL_OVERFLOW (a_4(D), b_5(D));
+     _2 = IMAGPART_EXPR <_6>;
+     if (_2 != 0)
+       goto <bb 4>; [35.00%]
+     else
+       goto <bb 3>; [65.00%]
+
+     <bb 3> [local count: 697932184]:
+     _1 = REALPART_EXPR <_6>;
+
+     <bb 4> [local count: 1073741824]:
+     # _3 = PHI <18446744073709551615(2), _1(3)>
+     =>
+     _3 = .SAT_MUL (a_4(D), b_5(D));  */
+
+static bool
+match_saturation_mul (gimple_stmt_iterator *gsi, gphi *phi)
+{
+  if (gimple_phi_num_args (phi) != 2)
+    return false;
+
+  tree ops[2];
+  tree phi_result = gimple_phi_result (phi);
+
+  if (!gimple_unsigned_integer_sat_mul (phi_result, ops, NULL))
+    return false;
+
+  return build_saturation_binary_arith_call_and_insert (gsi, IFN_SAT_MUL,
+                                                       phi_result, ops[0],
+                                                       ops[1]);
+}
+
 /*
  * Try to match saturation unsigned sub.
  *  <bb 2> [local count: 1073741824]:
@@ -6417,7 +6450,8 @@ math_opts_dom_walker::after_dom_children (basic_block bb)
 
       if (match_saturation_add (&gsi, phi)
          || match_saturation_sub (&gsi, phi)
-         || match_saturation_trunc (&gsi, phi))
+         || match_saturation_trunc (&gsi, phi)
+         || match_saturation_mul (&gsi, phi))
        remove_phi_node (&psi, /* release_lhs_p */ false);
     }
 
-- 
2.43.0

Reply via email to