https://gcc.gnu.org/g:7cf7149ec8303d0ed828fb7629417b28e6565d32

commit r16-885-g7cf7149ec8303d0ed828fb7629417b28e6565d32
Author: xuli <xu...@eswincomputing.com>
Date:   Fri Dec 27 07:03:14 2024 +0000

    Match:Support IMM=-1 for signed scalar SAT_ADD IMM form1
    
    This patch would like to support .SAT_ADD when IMM=-1.
    
    Form1:
    T __attribute__((noinline))                  \
    sat_s_add_imm_##T##_fmt_1##_##INDEX (T x)             \
    {                                            \
      T sum = (UT)x + (UT)IMM;                     \
      return (x ^ IMM) < 0                         \
        ? sum                                    \
        : (sum ^ x) >= 0                         \
          ? sum                                  \
          : x < 0 ? MIN : MAX;                   \
    }
    
    Take below form1 as example:
    DEF_SAT_S_ADD_IMM_FMT_1(0, int8_t, uint8_t, -1, INT8_MIN, INT8_MAX)
    
    Before this patch:
    __attribute__((noinline))
    int8_t sat_s_add_imm_int8_t_fmt_1_0 (int8_t x)
    {
      unsigned char x.0_1;
      unsigned char _2;
      unsigned char _3;
      int8_t iftmp.1_4;
      signed char _8;
      unsigned char _9;
      signed char _10;
    
      <bb 2> [local count: 1073741824]:
      x.0_1 = (unsigned char) x_5(D);
      _3 = -x.0_1;
      _10 = (signed char) _3;
      _8 = x_5(D) & _10;
      if (_8 < 0)
        goto <bb 4>; [1.40%]
      else
        goto <bb 3>; [98.60%]
    
      <bb 3> [local count: 434070867]:
      _2 = x.0_1 + 255;
    
      <bb 4> [local count: 1073741824]:
      # _9 = PHI <_2(3), 128(2)>
      iftmp.1_4 = (int8_t) _9;
      return iftmp.1_4;
    
    }
    
    After this patch:
    __attribute__((noinline))
    int8_t sat_s_add_imm_int8_t_fmt_1_0 (int8_t x)
    {
      int8_t _4;
    
      <bb 2> [local count: 1073741824]:
      gimple_call <.SAT_ADD, _4, x_5(D), 255> [tail call]
      gimple_return <_4>
    
    }
    
    The below test suites are passed for this patch:
    1. The rv64gcv fully regression tests.
    2. The x86 bootstrap tests.
    3. The x86 fully regression tests.
    
    Signed-off-by: Li Xu <xu...@eswincomputing.com>
    
    gcc/ChangeLog:
    
            * match.pd: Add signed scalar SAT_ADD IMM form1 with IMM=-1 
matching.
            * tree-ssa-math-opts.cc (match_unsigned_saturation_add): Adapt 
function name.
            (match_saturation_add_with_assign): Match signed and unsigned 
SAT_ADD with assign.
            (math_opts_dom_walker::after_dom_children): Match imm=-1 signed 
SAT_ADD with NOP_EXPR case.

Diff:
---
 gcc/match.pd              | 19 ++++++++++++++++++-
 gcc/tree-ssa-math-opts.cc | 30 +++++++++++++++++++++++++-----
 2 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index 27f662f9714b..50bd853b39a8 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3461,7 +3461,24 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
                        (bit_xor:c @0 INTEGER_CST@3)) integer_zerop)
         (signed_integer_sat_val @0)
         @2)
-  (if (wi::bit_and (wi::to_wide (@1), wi::to_wide (@3)) == 0))))
+  (if (wi::bit_and (wi::to_wide (@1), wi::to_wide (@3)) == 0)))
+
+(match (signed_integer_sat_add @0 @1)
+  /* T SUM = (T)((UT)X + (UT)-1);
+     SAT_S_ADD = (X ^ -1) < 0 ? SUM : (X ^ SUM) >= 0 ? SUM
+                                                     : (x < 0) ? MIN : MAX  */
+  (convert (cond^ (lt (bit_and:c @0 (nop_convert (negate (nop_convert @0))))
+             integer_zerop)
+        INTEGER_CST@2
+        (plus (nop_convert @0) integer_all_onesp@1)))
+   (with
+    {
+     unsigned precision = TYPE_PRECISION (type);
+     wide_int c1 = wi::to_wide (@1);
+     wide_int c2 = wi::to_wide (@2);
+     wide_int sum = wi::add (c1, c2);
+    }
+    (if (wi::eq_p (sum, wi::max_value (precision, SIGNED)))))))
 
 /* Saturation sub for signed integer.  */
 (if (INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type))
diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
index eb03ebe102ad..7e819f37446c 100644
--- a/gcc/tree-ssa-math-opts.cc
+++ b/gcc/tree-ssa-math-opts.cc
@@ -4104,15 +4104,34 @@ build_saturation_binary_arith_call_and_insert 
(gimple_stmt_iterator *gsi,
  *   _10 = -_9;
  *   _12 = _7 | _10;
  *   =>
- *   _12 = .SAT_ADD (_4, _6);  */
+ *   _12 = .SAT_ADD (_4, _6);
+ *
+ * Try to match IMM=-1 saturation signed add with assign.
+ * <bb 2> [local count: 1073741824]:
+ * x.0_1 = (unsigned char) x_5(D);
+ * _3 = -x.0_1;
+ * _10 = (signed char) _3;
+ * _8 = x_5(D) & _10;
+ * if (_8 < 0)
+ *   goto <bb 4>; [1.40%]
+ * else
+ *   goto <bb 3>; [98.60%]
+ * <bb 3> [local count: 434070867]:
+ * _2 = x.0_1 + 255;
+ * <bb 4> [local count: 1073741824]:
+ * # _9 = PHI <_2(3), 128(2)>
+ * _4 = (int8_t) _9;
+ *   =>
+ * _4 = .SAT_ADD (x_5, -1); */
 
 static void
-match_unsigned_saturation_add (gimple_stmt_iterator *gsi, gassign *stmt)
+match_saturation_add_with_assign (gimple_stmt_iterator *gsi, gassign *stmt)
 {
   tree ops[2];
   tree lhs = gimple_assign_lhs (stmt);
 
-  if (gimple_unsigned_integer_sat_add (lhs, ops, NULL))
+  if (gimple_unsigned_integer_sat_add (lhs, ops, NULL)
+      || gimple_signed_integer_sat_add (lhs, ops, NULL))
     build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_ADD, lhs,
                                                    ops[0], ops[1]);
 }
@@ -6403,7 +6422,7 @@ math_opts_dom_walker::after_dom_children (basic_block bb)
              break;
 
            case PLUS_EXPR:
-             match_unsigned_saturation_add (&gsi, as_a<gassign *> (stmt));
+             match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
              match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
              /* fall-through  */
            case MINUS_EXPR:
@@ -6429,7 +6448,7 @@ math_opts_dom_walker::after_dom_children (basic_block bb)
              break;
 
            case BIT_IOR_EXPR:
-             match_unsigned_saturation_add (&gsi, as_a<gassign *> (stmt));
+             match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
              match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
              /* fall-through  */
            case BIT_XOR_EXPR:
@@ -6450,6 +6469,7 @@ math_opts_dom_walker::after_dom_children (basic_block bb)
 
            case NOP_EXPR:
              match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
+             match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
              break;
 
            default:;

Reply via email to