]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Match: Add form 5 of unsigned SAT_MUL for mul
authorPan Li <pan2.li@intel.com>
Fri, 19 Sep 2025 06:54:47 +0000 (14:54 +0800)
committerPan Li <pan2.li@intel.com>
Wed, 24 Sep 2025 02:35:07 +0000 (10:35 +0800)
This patch would like to try to match the the unsigned
SAT_MUL form 5, aka below:

  #define DEF_SAT_U_MUL_FMT_5(NT, WT)             \
  NT __attribute__((noinline))                    \
  sat_u_mul_##NT##_from_##WT##_fmt_5 (NT a, NT b) \
  {                                               \
    WT x = (WT)a * (WT)b;                         \
    NT hi = x >> (sizeof(NT) * 8);                \
    NT lo = (NT)x;                                \
    return lo | -!!hi;                            \
  }

  while WT is uint16_t, uint32_t and uint64_t.
  and T is uint8_t, uint16_t, uint32_t.

gcc/ChangeLog:

* match.pd: Add pattern of mult and reuse the widen-mul
by for keyword.

Signed-off-by: Pan Li <pan2.li@intel.com>
gcc/match.pd

index 2e629fd31ceaec3369b81136b7739ec0c72105ff..b3fd26e18dddc9a7aa13aba725afa84b7b247418 100644 (file)
@@ -3695,31 +3695,36 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
       bool c2_is_type_precision_p = c2 == prec;
      }
      (if (widen_prec > prec && c2_is_type_precision_p && c4_is_max_p)))))
-  (match (unsigned_integer_sat_mul @0 @1)
-   /* SAT_U_MUL (X, Y) = {
-       WT x = (WT)a * (WT)b;
-       NT hi = x >> (sizeof(NT) * 8);
-       NT lo = (NT)x;
-       return lo | -!!hi;
-      } while WT is uint128_t, T is uint8_t, uint16_t, uint32_t or uint64_t.  */
-   (convert1?
-    (bit_ior (convert? (negate (convert (ne (convert (rshift @3 INTEGER_CST@2))
-                                           integer_zerop))))
-            (convert (widen_mult:c@3 (convert@4 @0)
-                                     (convert@5 @1)))))
-   (if (types_match (type, @0, @1))
-    (with
-     {
-      unsigned widen_prec = TYPE_PRECISION (TREE_TYPE (@3));
-      unsigned cvt4_prec = TYPE_PRECISION (TREE_TYPE (@4));
-      unsigned cvt5_prec = TYPE_PRECISION (TREE_TYPE (@5));
-      bool widen_mult_p = cvt4_prec == cvt5_prec && widen_prec == cvt5_prec * 2;
-
-      unsigned c2 = tree_to_uhwi (@2);
-      unsigned prec = TYPE_PRECISION (type);
-      bool c2_is_type_precision_p = c2 == prec;
-     }
-     (if (widen_mult_p && c2_is_type_precision_p)))))
+  (for mult_op (mult widen_mult)
+   (match (unsigned_integer_sat_mul @0 @1)
+    /* SAT_U_MUL (X, Y) = {
+        WT x = (WT)a * (WT)b;
+        NT hi = x >> (sizeof(NT) * 8);
+         NT lo = (NT)x;
+         return lo | -!!hi;
+       } while WT is uint128_t, uint64_t, uint32_t, uint16_t,
+         and T is uint64_t, uint32_t, uint16_t, uint8_t.  */
+    (convert1?
+     (bit_ior
+      (convert?
+       (negate
+       (convert (ne (convert2? (rshift @3 INTEGER_CST@2)) integer_zerop))))
+      (convert (mult_op:c@3 (convert@4 @0) (convert@5 @1)))))
+    (if (types_match (type, @0, @1))
+     (with
+      {
+       unsigned prec = TYPE_PRECISION (type);
+       unsigned widen_prec = TYPE_PRECISION (TREE_TYPE (@3));
+       unsigned cvt4_prec = TYPE_PRECISION (TREE_TYPE (@4));
+       unsigned cvt5_prec = TYPE_PRECISION (TREE_TYPE (@5));
+
+       bool widen_mult_p = mult_op == WIDEN_MULT_EXPR && cvt4_prec == cvt5_prec
+        && widen_prec == cvt5_prec * 2;
+       bool mult_p = mult_op == MULT_EXPR && cvt4_prec == cvt5_prec
+        && cvt4_prec == widen_prec && widen_prec > prec;
+       bool c2_is_type_precision_p = tree_to_uhwi (@2) == prec;
+      }
+      (if (c2_is_type_precision_p && (mult_p || widen_mult_p)))))))
 )
 
 /* The boundary condition for case 10: IMM = 1: