Thanks Jeff and Richard for suggestion and reviewing.

Have another try in phiopt to do the convert from PHI to stmt = cond ? a : b.
It can perform the convert from PHI to stmt = cond ? a : b successfully, and 
then
the widen-mul is able to do the recog to .SAT_ADD.

For now, to limit the risck, the above convert from PHI to stmt = cond ? a : b 
only be performed when matched,
as well as the backend support the usadd standard name. Unfortunately, I am 
stuck in the case that when the lhs
is not matched, we need to clean up something like created stmt in previous, or 
we will have ICE for missing definition.

sat_add.c: In function ‘sat_add_u_3_uint8_t’:
sat_add.c:69:1: error: missing definition
   69 | SAT_ADD_U_3(uint8_t);
      | ^~~~~~~~~~~
for SSA_NAME: _6 in statement:
# VUSE <.MEM_14(D)>
return _6;
during GIMPLE pass: phiopt
dump file: sat_add.c.046t.phiopt1
sat_add.c:69:1: internal compiler error: verify_ssa failed
0x1db41ba verify_ssa(bool, bool
/home/pli/gcc/555/riscv-gnu-toolchain/gcc/__RISCV_BUILD__/../gcc/tree-ssa.cc:1203
0x18e3075 execute_function_todo
        
/home/pli/gcc/555/riscv-gnu-toolchain/gcc/__RISCV_BUILD__/../gcc/passes.cc:2096
0x18e1c52 do_per_function
        
/home/pli/gcc/555/riscv-gnu-toolchain/gcc/__RISCV_BUILD__/../gcc/passes.cc:1688
0x18e3222 execute_todo

I bet the reason is that we created new stmt like stmt_cond and stmt_val but we 
don't insert it.
Thus, there will be orphan nodes somewhere and we need something like rollback 
to recover the
gimple up to a point. I tried sorts of release_xx or likewise but seems not 
working.

So is there any suggest to take care of such gimple rollback or another 
solution for this? Below are
The function to perform the convert from PHI to stmt = cond ? a : b for 
reference, thanks a lot.

Pan

diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 918cf50b589..7982b65bac4 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -486,6 +486,88 @@ phiopt_early_allow (gimple_seq &seq, gimple_match_op &op)
     }
 }

+extern bool gimple_unsigned_integer_sat_add (tree, tree*, tree (*)(tree));
+
+/* Try to match the phi expr to the gimple cond. Return true if we can
+   perform the convert or return false.  There will be some restrictions
+   or such kind of conversion, aka:
+
+   1. Only selected pattern will try this convert.
+   2. The generated gassign matched the selected IFN pattern.
+   3. The backend has implement the standard name.
+
+   From:
+     <bb 2> :
+     _1 = x_3(D) + y_4(D);
+     if (_1 >= x_3(D))
+       goto <bb 3>; [INV]
+     else
+       goto <bb 4>; [INV]
+
+     <bb 3> :
+
+     <bb 4> :
+     # _2 = PHI <255(2), _1(3)>
+
+   To:
+     <bb 2> :
+     _1 = x_3(D) + y_4(D);
+     phi_cond_6 = _1 >= x_3(D);
+     _2 = phi_cond_6 ? _1 : 255; */
+
+static bool
+match_phi_to_gimple_cond (basic_block cond_bb, gphi *phi, tree arg0, tree arg1)
+{
+  gcond *cond = as_a <gcond *> (*gsi_last_bb (cond_bb));
+
+  if (!cond)
+    return false;
+
+  enum tree_code code = gimple_cond_code (cond);
+  tree phi_result = gimple_phi_result (phi);        
+  tree cond_tree = make_temp_ssa_name (boolean_type_node, NULL, "phi_cond");
+  tree cmp_tree = build2 (code, boolean_type_node, gimple_cond_lhs (cond),
+                         gimple_cond_rhs (cond));
+  tree rhs = build3 (COND_EXPR, TREE_TYPE (phi_result), cond_tree, arg0, arg1);
+
+  gassign *stmt_cond = gimple_build_assign (cond_tree, cmp_tree);
+  gassign *stmt_val = gimple_build_assign (phi_result, rhs);
+
+  tree ops[2];
+  tree lhs = gimple_assign_lhs (stmt_val);
+  bool matched_p = (gimple_unsigned_integer_sat_add (lhs, ops, NULL)
+    && direct_internal_fn_supported_p (IFN_SAT_ADD, TREE_TYPE (lhs),
+                                      OPTIMIZE_FOR_BOTH));
+
+  if (matched_p)
+    {
+      gimple_stmt_iterator gsi = gsi_last_bb (cond_bb);
+      gimple_stmt_iterator psi = gsi_for_stmt (phi);
+
+      gsi_insert_before (&gsi, stmt_cond, GSI_SAME_STMT);
+      gsi_insert_before (&gsi, stmt_val, GSI_SAME_STMT);
+      remove_phi_node (&psi, false);
+    }
+  else
+    {
+      // Clean up the stmt created, but non of blow works well.
+      // gsi = gsi_for_stmt (stmt_val); 
+      // gsi_remove (&gsi, true);
+      // release_defs (stmt_val);
+      // ggc_free (stmt_val);
+
+      // gsi = gsi_for_stmt (stmt_cond);
+      // gsi_remove (&gsi, true);
+      // release_defs (stmt_cond);
+      // ggc_free (stmt_cond);
+
+      // release_defs (stmt_cond);
+      // release_defs (stmt_val);
+      release_ssa_name (cond_tree);
+    }
+
+  return matched_p;
+}
+
/* gimple_simplify_phiopt is like gimple_simplify but designed for PHIOPT.
    Return NULL if nothing can be simplified or the resulting simplified value
    with parts pushed if EARLY_P was true. Also rejects non allowed tree code
@@ -826,6 +908,9 @@ match_simplify_replacement (basic_block cond_bb, 
basic_block middle_bb,
      So, given the condition COND, and the two PHI arguments, match and 
simplify
      can happen on (COND) ? arg0 : arg1. */

+  if (match_phi_to_gimple_cond (cond_bb, phi, arg0, arg1))
+    return true;
+
   stmt = last_nondebug_stmt (cond_bb);

   /* We need to know which is the true edge and which is the false


-----Original Message-----
From: Jeff Law <jeffreya...@gmail.com> 
Sent: Thursday, May 23, 2024 10:59 PM
To: Richard Biener <richard.guent...@gmail.com>; Li, Pan2 <pan2...@intel.com>
Cc: gcc-patches@gcc.gnu.org; juzhe.zh...@rivai.ai; kito.ch...@gmail.com; 
tamar.christ...@arm.com; pins...@gmail.com
Subject: Re: [PATCH v2] Match: Support __builtin_add_overflow branch form for 
unsigned SAT_ADD



On 5/23/24 6:14 AM, Richard Biener wrote:
> On Thu, May 23, 2024 at 1:08 PM Li, Pan2 <pan2...@intel.com> wrote:
>>
>> I have a try to convert the PHI from Part-A to Part-B, aka PHI to _2 = 
>> phi_cond ? _1 : 255.
>> And then we can do the matching on COND_EXPR in the underlying widen-mul 
>> pass.
>>
>> Unfortunately, meet some ICE when verify_gimple_phi in sccopy1 pass =>
>> sat_add.c:66:1: internal compiler error: tree check: expected class ‘type’, 
>> have ‘exceptional’ (error_mark) in useless_type_conversion_p, at 
>> gimple-expr.cc:86
> 
> Likely you have released _2, more comments below on your previous mail.
You can be sure by calling debug_tree () on the SSA_NAME node in 
question.  If it reports "in-free-list", then that's definitive that the 
SSA_NAME was released back to the SSA_NAME manager.  If that SSA_NAME is 
still in the IL, then that's very bad.

jeff

Reply via email to