public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc(refs/vendors/redhat/heads/gcc-8-branch)] tree-optimization/99954 - fix loop distribution memcpy classification
Date: Fri, 14 May 2021 14:55:16 +0000 (GMT)	[thread overview]
Message-ID: <20210514145516.58E313949F32@sourceware.org> (raw)

https://gcc.gnu.org/g:42f6f70f0a81257f715a96bb7f075d2485af4a1f

commit 42f6f70f0a81257f715a96bb7f075d2485af4a1f
Author: Richard Biener <rguenther@suse.de>
Date:   Wed Apr 7 13:17:05 2021 +0200

    tree-optimization/99954 - fix loop distribution memcpy classification
    
    This fixes bogus classification of a copy as memcpy.  We cannot use
    plain dependence analysis to decide between memcpy and memmove when
    it computes no dependence.  Instead we have to try harder later which
    the patch does for the gcc.dg/tree-ssa/ldist-24.c testcase by resorting
    to tree-affine to compute the difference between src and dest and
    compare against the copy size.
    
    2021-04-07  Richard Biener  <rguenther@suse.de>
    
            PR tree-optimization/99954
            * tree-loop-distribution.c: Include tree-affine.h.
            (generate_memcpy_builtin): Try using tree-affine to prove
            non-overlap.
            (loop_distribution::classify_builtin_ldst): Always classify
            as PKIND_MEMMOVE.
    
            * gcc.dg/torture/pr99954.c: New testcase.
    
    (cherry picked from commit b091cb1efa1881e93fb2e264daaab8876acf6800)

Diff:
---
 gcc/testsuite/gcc.dg/torture/pr99954.c | 30 ++++++++++++++++++++++++++++++
 gcc/tree-loop-distribution.c           | 17 +++++++++++++++--
 2 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/torture/pr99954.c b/gcc/testsuite/gcc.dg/torture/pr99954.c
new file mode 100644
index 00000000000..7d447035912
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr99954.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+
+#include <assert.h>
+
+#define CONTAINER_KIND union
+
+typedef CONTAINER_KIND container { int value; } container;
+
+void move(container* end, container* start) {
+    container* p;
+    for (p = end; p > start; p--) {
+	(p)->value = (p-1)->value;
+    }
+}
+
+#define N 100
+
+int main(int argc, char* argv[]) {
+    container vals[N];
+    int i;
+    for (i=0; i<N; i++) {
+        vals[i].value = argc + i;
+    }
+    move(&vals[N-1], &vals[0]);
+    assert(vals[0].value == argc + 0);
+    for (i=1; i<N; i++) {
+        assert(vals[i].value == argc + i - 1);
+    }
+    return 0;
+}
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index e257c9bc433..761d577f390 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -116,6 +116,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "params.h"
 #include "tree-vectorizer.h"
 #include "tree-eh.h"
+#include "tree-affine.h"
 
 
 #define MAX_DATAREFS_NUM \
@@ -1060,6 +1061,18 @@ generate_memcpy_builtin (struct loop *loop, partition *partition)
     kind = BUILT_IN_MEMCPY;
   else
     kind = BUILT_IN_MEMMOVE;
+  /* Try harder if we're copying a constant size.  */
+  if (kind == BUILT_IN_MEMMOVE && poly_int_tree_p (nb_bytes))
+    {
+      aff_tree asrc, adest;
+      tree_to_aff_combination (src, ptr_type_node, &asrc);
+      tree_to_aff_combination (dest, ptr_type_node, &adest);
+      aff_combination_scale (&adest, -1);
+      aff_combination_add (&asrc, &adest);
+      if (aff_comb_cannot_overlap_p (&asrc, wi::to_poly_widest (nb_bytes),
+				     wi::to_poly_widest (nb_bytes)))
+	kind = BUILT_IN_MEMCPY;
+    }
 
   dest = force_gimple_operand_gsi (&gsi, dest, true, NULL_TREE,
 				   false, GSI_CONTINUE_LINKING);
@@ -1591,11 +1604,11 @@ classify_builtin_ldst (loop_p loop, struct graph *rdg, partition *partition,
   /* Now check that if there is a dependence.  */
   ddr_p ddr = get_data_dependence (rdg, src_dr, dst_dr);
 
-  /* Classify as memcpy if no dependence between load and store.  */
+  /* Classify as memmove if no dependence between load and store.  */
   if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
     {
       partition->builtin = alloc_builtin (dst_dr, src_dr, base, src_base, size);
-      partition->kind = PKIND_MEMCPY;
+      partition->kind = PKIND_MEMMOVE;
       return;
     }


                 reply	other threads:[~2021-05-14 14:55 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210514145516.58E313949F32@sourceware.org \
    --to=jakub@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).