https://gcc.gnu.org/g:261bcbf171ffff021d20323ff0271f1e33850ff4

commit r13-9615-g261bcbf171ffff021d20323ff0271f1e33850ff4
Author: Richard Sandiford <richard.sandif...@arm.com>
Date:   Thu Apr 24 14:21:32 2025 +0100

    Avoid using POINTER_DIFF_EXPR for overlap checks [PR119399]
    
    In r10-4803-g8489e1f45b50600c I'd used POINTER_DIFF_EXPR to subtract
    the two pointers involved in an overlap test.  I'm not sure whether
    I'd specifically chosen that over MINUS_EXPR or not; if so, the only
    reason I can think of is that it is probably faster on targets with
    PSImode pointers.  Regardless, as the PR points out, subtracting
    unrelated pointers using POINTER_DIFF_EXPR is undefined behaviour.
    
    gcc/
            PR tree-optimization/119399
            * tree-data-ref.cc (create_waw_or_war_checks): Use a MINUS_EXPR
            on two converted pointers, rather than converting a 
POINTER_DIFF_EXPR
            on the pointers.
    
    gcc/testsuite/
            PR tree-optimization/119399
            * gcc.dg/vect/pr119399.c: New test.
    
    (cherry picked from commit 4c8c373495d7d863dfb7102726ac3b4b41685df4)

Diff:
---
 gcc/testsuite/gcc.dg/vect/pr119399.c | 10 ++++++++++
 gcc/tree-data-ref.cc                 |  7 ++++---
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/vect/pr119399.c 
b/gcc/testsuite/gcc.dg/vect/pr119399.c
new file mode 100644
index 000000000000..8d868f44b672
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr119399.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fdump-tree-vect-raw" } */
+
+void foo(int *p, int *q, int n)
+{
+  for (int i = 0; i < n; i++)
+    p[i] = q[i] + 1;
+}
+
+/* { dg-final { scan-tree-dump-not {<pointer_diff_expr,} "vect" } } */
diff --git a/gcc/tree-data-ref.cc b/gcc/tree-data-ref.cc
index b6823d2bb16c..5b32d6a4dfb5 100644
--- a/gcc/tree-data-ref.cc
+++ b/gcc/tree-data-ref.cc
@@ -2487,9 +2487,10 @@ create_waw_or_war_checks (tree *cond_expr,
   limit = fold_build2 (PLUS_EXPR, sizetype, limit,
                       size_int (last_chunk_a + last_chunk_b));
 
-  tree subject = fold_build2 (POINTER_DIFF_EXPR, ssizetype, addr_b, addr_a);
-  subject = fold_build2 (PLUS_EXPR, sizetype,
-                        fold_convert (sizetype, subject), bias);
+  tree subject = fold_build2 (MINUS_EXPR, sizetype,
+                             fold_convert (sizetype, addr_b),
+                             fold_convert (sizetype, addr_a));
+  subject = fold_build2 (PLUS_EXPR, sizetype, subject, bias);
 
   *cond_expr = fold_build2 (GT_EXPR, boolean_type_node, subject, limit);
   if (dump_enabled_p ())

Reply via email to