https://gcc.gnu.org/g:02cc8494745c4235890ad58e93b5acce5a89a775

commit r15-2149-g02cc8494745c4235890ad58e93b5acce5a89a775
Author: Pan Li <pan2...@intel.com>
Date:   Thu Jul 18 20:16:34 2024 +0800

    Match: Only allow single use of MIN_EXPR for SAT_TRUNC form 2 [PR115863]
    
    The SAT_TRUNC form 2 has below pattern matching.
    From:
      _18 = MIN_EXPR <left_8, 4294967295>;
      iftmp.0_11 = (unsigned int) _18;
    
    To:
      _18 = MIN_EXPR <left_8, 4294967295>;
      iftmp.0_11 = .SAT_TRUNC (left_8);
    
    But if there is another use of _18 like below,  the transform to the
    .SAT_TRUNC may have no earnings.  For example:
    
    From:
      _18 = MIN_EXPR <left_8, 4294967295>; // op_0 def
      iftmp.0_11 = (unsigned int) _18;     // op_0
      stream.avail_out = iftmp.0_11;
      left_37 = left_8 - _18;              // op_0 use
    
    To:
      _18 = MIN_EXPR <left_8, 4294967295>; // op_0 def
      iftmp.0_11 = .SAT_TRUNC (left_8);
      stream.avail_out = iftmp.0_11;
      left_37 = left_8 - _18;              // op_0 use
    
    Pattern recog to .SAT_TRUNC cannot eliminate MIN_EXPR as above.  Then the
    backend (for example x86/riscv) will have additional 2-3 more insns
    after pattern recog besides the MIN_EXPR.  Thus,  keep the normal truncation
    as is should be the better choose.
    
    The below testsuites are passed for this patch:
    1. The rv64gcv fully regression tests.
    2. The x86 bootstrap tests.
    3. The x86 fully regression tests.
    
            PR target/115863
    
    gcc/ChangeLog:
    
            * match.pd: Add single_use check for .SAT_TRUNC form 2.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/i386/pr115863-1.c: New test.
    
    Signed-off-by: Pan Li <pan2...@intel.com>

Diff:
---
 gcc/match.pd                               | 15 ++++++++++--
 gcc/testsuite/gcc.target/i386/pr115863-1.c | 37 ++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/gcc/match.pd b/gcc/match.pd
index 6818856991c6..cf359b0ec0f0 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3252,10 +3252,21 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 
 /* Unsigned saturation truncate, case 2, sizeof (WT) > sizeof (NT).
    SAT_U_TRUNC = (NT)(MIN_EXPR (X, 255)).  */
+/* If Op_0 def is MIN_EXPR and not single_use.  Aka below pattern:
+
+     _18 = MIN_EXPR <left_8, 4294967295>; // op_0 def
+     iftmp.0_11 = (unsigned int) _18;     // op_0
+     stream.avail_out = iftmp.0_11;
+     left_37 = left_8 - _18;              // op_0 use
+
+   Transfer to .SAT_TRUNC will have MIN_EXPR still live.  Then the backend
+   (for example x86/riscv) will have 2-3 more insns generation for .SAT_TRUNC
+   besides the MIN_EXPR.  Thus,  keep the normal truncation as is should be
+   the better choose.  */
 (match (unsigned_integer_sat_trunc @0)
- (convert (min @0 INTEGER_CST@1))
+ (convert (min@2 @0 INTEGER_CST@1))
  (if (INTEGRAL_TYPE_P (type) && TYPE_UNSIGNED (type)
-      && TYPE_UNSIGNED (TREE_TYPE (@0)))
+      && TYPE_UNSIGNED (TREE_TYPE (@0)) && single_use (@2))
  (with
   {
    unsigned itype_precision = TYPE_PRECISION (TREE_TYPE (@0));
diff --git a/gcc/testsuite/gcc.target/i386/pr115863-1.c 
b/gcc/testsuite/gcc.target/i386/pr115863-1.c
new file mode 100644
index 000000000000..a672f62cec54
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr115863-1.c
@@ -0,0 +1,37 @@
+/* PR target/115863 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-rtl-expand-details" } */
+
+#include <stdint-gcc.h>
+
+typedef struct z_stream_s {
+    uint32_t     avail_out;
+} z_stream;
+
+typedef z_stream *z_streamp;
+
+extern int deflate (z_streamp strmp);
+
+int compress2 (uint64_t *destLen)
+{
+  z_stream stream;
+  int err;
+  const uint32_t max = (uint32_t)(-1);
+  uint64_t left;
+
+  left = *destLen;
+
+  stream.avail_out = 0;
+
+  do {
+        if (stream.avail_out == 0) {
+            stream.avail_out = left > (uint64_t)max ? max : (uint32_t)left;
+            left -= stream.avail_out;
+        }
+        err = deflate(&stream);
+    } while (err == 0);
+
+  return err;
+}
+
+/* { dg-final { scan-rtl-dump-not ".SAT_TRUNC " "expand" } } */

Reply via email to