From: Pan Li <[email protected]>

During the match pattern of SAT_U_MUL form 7, we found there is
a pattern like below:

(nop_convert)(a bit_op (convert b))

which result in the pattern match of SAT_U_MUL complicated and
unintuitive.  According to the suggestion of Richard, we would
like to simply it to blew:

(convert a) bit_op (convert b)

which is more friendly for reading and bit_op.  There are three
bit_op here, aka bit_ior, bit_and and bit_xor.

gcc/ChangeLog:

        * match.pd: Add simplfy to fold outer convert of bit_op
        to inner captures.

Signed-off-by: Pan Li <[email protected]>
---
 gcc/match.pd | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/gcc/match.pd b/gcc/match.pd
index 3cd9ab1e9b0..8d0d7b907ea 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3653,6 +3653,25 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
         || (wi::eq_p (int_cst_1, itype_max) && wi::eq_p (int_cst_2, limit_1)))
         && wi::eq_p (int_cst_3, otype_max)))))))
 
+/* (nop_convert)(a bit_op (convert b)) => bit_op ((convert a), (convert b))  */
+(if (INTEGRAL_TYPE_P (type))
+ (for bit_op (bit_ior bit_and bit_xor)
+  (simplify
+   (convert (bit_op:c @0 (convert @1)))
+   (with
+    {
+      unsigned prec = TYPE_PRECISION (type);
+      tree type_c0 = TREE_TYPE (@0);
+      tree type_c1 = TREE_TYPE (@1);
+      unsigned prec_c0 = TYPE_PRECISION (type_c0);
+      unsigned prec_c1 = TYPE_PRECISION (type_c1);
+    }
+    (if (INTEGRAL_TYPE_P (type_c0)
+        && INTEGRAL_TYPE_P (type_c1)
+        && prec_c1 > prec
+        && prec == prec_c0)
+    (bit_op:type (convert @0) (convert @1)))))))
+
 /* Saturation mult for unsigned integer.  */
 (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type))
  (for mult_op (mult widen_mult)
-- 
2.43.0

Reply via email to