diff mbox series

introduce effective-target fold_memcpy

Message ID 4998fc5c-9bd1-f2f0-282d-0c3c0b1fe808@gmail.com
State New
Headers show
Series introduce effective-target fold_memcpy | expand

Commit Message

Martin Sebor Jan. 18, 2019, 11:24 p.m. UTC
Some of the -Warray-bounds and -Wrestrict tests are prone to failing
on targets like arm-eabi and others that use different parameters to
decide which memcpy calls should be folded to MEM_REF (those that do
are copies of small power-of-two sizes where the power tends to vary
from target to target and may be as little as 1).  The failures then
waste the time of those who maintain those secondary targets reporting
failures (see * below), as well as those who wrote the tests debugging 
the problems and working around them.

To reduce this effort (and ideally avoid these regressions going
forward) the attached patch adds a new effective-target to the test
harness: fold_memcpy_N.  It detects the target's willingness to fold
memcpy call of the given size (N).  While testing this with the arm
cross-compiler I also tweaked the tests that #include standard
headers to only do so when __has_include says the header exists.
This lets the tests pass even when using a cross-compiler without
library headers installed (my default MO).  If/when the warnings
are improved to detect the problems regardless of the folding as
I'm hoping to eventually do, this new effective-target feature
can be removed.

Martin

[*] https://gcc.gnu.org/ml/gcc-patches/2019-01/msg01056.html

Comments

Richard Biener Jan. 21, 2019, 8:18 a.m. UTC | #1
On Sat, Jan 19, 2019 at 12:25 AM Martin Sebor <msebor@gmail.com> wrote:
>
> Some of the -Warray-bounds and -Wrestrict tests are prone to failing
> on targets like arm-eabi and others that use different parameters to
> decide which memcpy calls should be folded to MEM_REF (those that do
> are copies of small power-of-two sizes where the power tends to vary
> from target to target and may be as little as 1).  The failures then
> waste the time of those who maintain those secondary targets reporting
> failures (see * below), as well as those who wrote the tests debugging
> the problems and working around them.
>
> To reduce this effort (and ideally avoid these regressions going
> forward) the attached patch adds a new effective-target to the test
> harness: fold_memcpy_N.  It detects the target's willingness to fold
> memcpy call of the given size (N).  While testing this with the arm
> cross-compiler I also tweaked the tests that #include standard
> headers to only do so when __has_include says the header exists.
> This lets the tests pass even when using a cross-compiler without
> library headers installed (my default MO).  If/when the warnings
> are improved to detect the problems regardless of the folding as
> I'm hoping to eventually do, this new effective-target feature
> can be removed.

But all the memcpy folding does is see whether the target can
access unaligned {2,4,8,<max-int-mode-size>} memory.  So
a effective target unaligned_move_{2,4,8...} would be better and
possibly useful in other contexts?  memcpy folding might be indeed
a nice vehicle to test this property.

Thus, I guess I'm only asking to rename the effective target keyword.

Btw, new effective targets need documenting in sourcebuild.texi

Richard.

> Martin
>
> [*] https://gcc.gnu.org/ml/gcc-patches/2019-01/msg01056.html
Martin Sebor Jan. 21, 2019, 8:22 p.m. UTC | #2
On 1/21/19 1:18 AM, Richard Biener wrote:
> On Sat, Jan 19, 2019 at 12:25 AM Martin Sebor <msebor@gmail.com> wrote:
>>
>> Some of the -Warray-bounds and -Wrestrict tests are prone to failing
>> on targets like arm-eabi and others that use different parameters to
>> decide which memcpy calls should be folded to MEM_REF (those that do
>> are copies of small power-of-two sizes where the power tends to vary
>> from target to target and may be as little as 1).  The failures then
>> waste the time of those who maintain those secondary targets reporting
>> failures (see * below), as well as those who wrote the tests debugging
>> the problems and working around them.
>>
>> To reduce this effort (and ideally avoid these regressions going
>> forward) the attached patch adds a new effective-target to the test
>> harness: fold_memcpy_N.  It detects the target's willingness to fold
>> memcpy call of the given size (N).  While testing this with the arm
>> cross-compiler I also tweaked the tests that #include standard
>> headers to only do so when __has_include says the header exists.
>> This lets the tests pass even when using a cross-compiler without
>> library headers installed (my default MO).  If/when the warnings
>> are improved to detect the problems regardless of the folding as
>> I'm hoping to eventually do, this new effective-target feature
>> can be removed.
> 
> But all the memcpy folding does is see whether the target can
> access unaligned {2,4,8,<max-int-mode-size>} memory.  So
> a effective target unaligned_move_{2,4,8...} would be better and
> possibly useful in other contexts?  memcpy folding might be indeed
> a nice vehicle to test this property.
> 
> Thus, I guess I'm only asking to rename the effective target keyword.

I did this but after some more reading I no longer think we need it.

> Btw, new effective targets need documenting in sourcebuild.texi

Thanks for the reminder!  While adding the new keyword I came across
non_strict_align.  It looks like it's pretty much same thing as what
I'm trying to add.  It's used in gcc.dg/memmove-4.c and memcpy-3.c
(besides a few other tests) to test the folding whose absence
the warnings depend on.

So I've simplified the patch to make use of non_strict_align instead.
I've verified the tests pass with arm-eabi, sparc-solaris2.11, and
x86_64.

Martin

> 
> Richard.
> 
>> Martin
>>
>> [*] https://gcc.gnu.org/ml/gcc-patches/2019-01/msg01056.html
gcc/testsuite/ChangeLog:

	* c-c++-common/Warray-bounds-2.c: Include headers only if they exist.
	* c-c++-common/Warray-bounds-3.c: Make xfails conditional on target
	non_strict_align.
	* c-c++-common/Wrestrict-2.c: Include headers only if they exist.
	* c-c++-common/Wrestrict.c: Make xfails conditional on target
	non_strict_align.

Index: gcc/testsuite/c-c++-common/Warray-bounds-2.c
===================================================================
--- gcc/testsuite/c-c++-common/Warray-bounds-2.c	(revision 268086)
+++ gcc/testsuite/c-c++-common/Warray-bounds-2.c	(working copy)
@@ -8,13 +8,28 @@
    { dg-do compile }
    { dg-options "-O2 -Warray-bounds -Wno-stringop-overflow" } */
 
-#include <stddef.h>
-#include <string.h>
+#if __has_include (<stddef.h>)
+#  include <stddef.h>
+#else
+/* For cross-compilers.  */
+typedef __PTRDIFF_TYPE__   ptrdiff_t;
+typedef __SIZE_TYPE__      size_t;
+#endif
 
-#undef memcpy
-#undef strcpy
-#undef strncpy
+#if __has_include (<string.h>)
+#  include <string.h>
+#  undef memcpy
+#  undef strcat
+#  undef strcpy
+#  undef strncpy
+#else
+extern void* memcpy (void*, const void*, size_t);
+extern char* strcat (char*, const char*);
+extern char* strcpy (char*, const char*);
+extern char* strncpy (char*, const char*, size_t);
+#endif
 
+
 #define MAX  (__SIZE_MAX__ / 2)
 
 void sink (void*);
Index: gcc/testsuite/c-c++-common/Warray-bounds-3.c
===================================================================
--- gcc/testsuite/c-c++-common/Warray-bounds-3.c	(revision 268086)
+++ gcc/testsuite/c-c++-common/Warray-bounds-3.c	(working copy)
@@ -158,7 +158,7 @@ void test_memcpy_overflow (char *d, const char *s,
      but known access size is detected.  This works except with small
      sizes that are powers of 2 due to bug .  */
   T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 1);
-  T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 2);  /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 2 accessing array " "bug " { xfail *-*-* } } */
+  T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 2);  /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 2 accessing array " "bug " { xfail non_strict_align } } */
   T (char, 1, arr + SR (DIFF_MAX - 2, DIFF_MAX), s, 3);  /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 3 accessing array " "memcpy" } */
   T (char, 1, arr + SR (DIFF_MAX - 4, DIFF_MAX), s, 5);  /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 5 accessing array " "memcpy" } */
 }
Index: gcc/testsuite/c-c++-common/Wrestrict-2.c
===================================================================
--- gcc/testsuite/c-c++-common/Wrestrict-2.c	(revision 268086)
+++ gcc/testsuite/c-c++-common/Wrestrict-2.c	(working copy)
@@ -8,8 +8,30 @@
    { dg-do compile }
    { dg-options "-O2 -Wrestrict" } */
 
-#include <string.h>
+#if __has_include (<stddef.h>)
+#  include <stddef.h>
+#else
+/* For cross-compilers.  */
+typedef __PTRDIFF_TYPE__   ptrdiff_t;
+typedef __SIZE_TYPE__      size_t;
+#endif
 
+#if __has_include (<string.h>)
+#  include <string.h>
+#  undef memcpy
+#  undef strcat
+#  undef strcpy
+#  undef strncat
+#  undef strncpy
+#else
+extern void* memcpy (void*, const void*, size_t);
+extern char* strcat (char*, const char*);
+extern char* strcpy (char*, const char*);
+extern char* strncat (char*, const char*, size_t);
+extern char* strncpy (char*, const char*, size_t);
+#endif
+
+
 static void wrap_memcpy (void *d, const void *s, size_t n)
 {
   memcpy (d, s, n);   /* { dg-warning "accessing 2 bytes at offsets 0 and 1 overlaps 1 byte at offset 1" "memcpy" } */
Index: gcc/testsuite/c-c++-common/Wrestrict.c
===================================================================
--- gcc/testsuite/c-c++-common/Wrestrict.c	(revision 268086)
+++ gcc/testsuite/c-c++-common/Wrestrict.c	(working copy)
@@ -53,8 +53,11 @@ void test_memcpy_cst (void *d, const void *s)
 
   T (a, a, 0);
 
-  /* This isn't detected because memcpy calls with small power-of-2 sizes
-     are intentionally folded into safe copies equivalent to memmove.
+  /* This isn't detected because memcpy calls with size of 1 are
+     intentionally folded into safe copies equivalent to memmove,
+     regardless of the target (larger power-of-2 copies may or
+     may not be folded depending on the target -- see non_strict_align
+     below, for example).
      It's marked xfail only because there is value in detecting such
      invalid calls for portability, and as a reminder of why it isn't
      diagnosed.  */
@@ -192,7 +195,7 @@ void test_memcpy_range (char *d, size_t sz)
   T (a + ir, a, 2);
   T (a + ir, a, 3);
   /* The following fails because the size is a small power of 2.  */
-  T (a + ir, a, 4);               /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps between 1 and 2 bytes at offset \\\[3, 2]" "memcpy" { xfail *-*-*} } */
+  T (a + ir, a, 4);               /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps between 1 and 2 bytes at offset \(\\\[3, 2]|\\\[2, 3]\)" "pr79220" { xfail non_strict_align } } */
   T (a + ir, a, 5);               /* { dg-warning "accessing 5 bytes at offsets \\\[2, 3] and 0 overlaps between 2 and 3 bytes at offset \\\[2, 3]" "memcpy" } */
 
   T (d + ir, d, 0);
@@ -199,12 +202,12 @@ void test_memcpy_range (char *d, size_t sz)
   T (d + ir, d, 1);
   T (d + ir, d, 2);
   T (d + ir, d, 3);
-  T (d + ir, d, 4);               /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps 1 byte at offset 3" "bug 79220" { xfail *-*-* } } */
+  T (d + ir, d, 4);               /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps between 1 and 2 bytes at offset \\\[2, 3]" "pr79220" { xfail non_strict_align } } */
   T (d + ir, d, 5);               /* { dg-warning "accessing 5 bytes at offsets \\\[2, 3] and 0 overlaps between 2 and 3 bytes at offset \\\[2, 3]" "memcpy" } */
 
   /* Because the size is constant and a power of 2 the following is
      folded too early to detect the overlap.  */
-  T (d + ir, d, 4);               /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps 2 byte at offset 2" "memcpy" { xfail *-*-* } } */
+  T (d + ir, d, 4);               /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps between 1 and 2 bytes at offset \\\[2, 3]" "pr79220" { xfail non_strict_align } } */
   T (d + ir, d, 5);               /* { dg-warning "accessing 5 bytes at offsets \\\[2, 3] and 0 overlaps between 2 and 3 bytes at offset \\\[2, 3]" "memcpy" } */
 
   /* Exercise the full range of size_t.  */
Richard Biener Jan. 22, 2019, 12:03 p.m. UTC | #3
On Mon, Jan 21, 2019 at 9:23 PM Martin Sebor <msebor@gmail.com> wrote:
>
> On 1/21/19 1:18 AM, Richard Biener wrote:
> > On Sat, Jan 19, 2019 at 12:25 AM Martin Sebor <msebor@gmail.com> wrote:
> >>
> >> Some of the -Warray-bounds and -Wrestrict tests are prone to failing
> >> on targets like arm-eabi and others that use different parameters to
> >> decide which memcpy calls should be folded to MEM_REF (those that do
> >> are copies of small power-of-two sizes where the power tends to vary
> >> from target to target and may be as little as 1).  The failures then
> >> waste the time of those who maintain those secondary targets reporting
> >> failures (see * below), as well as those who wrote the tests debugging
> >> the problems and working around them.
> >>
> >> To reduce this effort (and ideally avoid these regressions going
> >> forward) the attached patch adds a new effective-target to the test
> >> harness: fold_memcpy_N.  It detects the target's willingness to fold
> >> memcpy call of the given size (N).  While testing this with the arm
> >> cross-compiler I also tweaked the tests that #include standard
> >> headers to only do so when __has_include says the header exists.
> >> This lets the tests pass even when using a cross-compiler without
> >> library headers installed (my default MO).  If/when the warnings
> >> are improved to detect the problems regardless of the folding as
> >> I'm hoping to eventually do, this new effective-target feature
> >> can be removed.
> >
> > But all the memcpy folding does is see whether the target can
> > access unaligned {2,4,8,<max-int-mode-size>} memory.  So
> > a effective target unaligned_move_{2,4,8...} would be better and
> > possibly useful in other contexts?  memcpy folding might be indeed
> > a nice vehicle to test this property.
> >
> > Thus, I guess I'm only asking to rename the effective target keyword.
>
> I did this but after some more reading I no longer think we need it.
>
> > Btw, new effective targets need documenting in sourcebuild.texi
>
> Thanks for the reminder!  While adding the new keyword I came across
> non_strict_align.  It looks like it's pretty much same thing as what
> I'm trying to add.  It's used in gcc.dg/memmove-4.c and memcpy-3.c
> (besides a few other tests) to test the folding whose absence
> the warnings depend on.
>
> So I've simplified the patch to make use of non_strict_align instead.
> I've verified the tests pass with arm-eabi, sparc-solaris2.11, and
> x86_64.

OK.

> Martin
>
> >
> > Richard.
> >
> >> Martin
> >>
> >> [*] https://gcc.gnu.org/ml/gcc-patches/2019-01/msg01056.html
>
diff mbox series

Patch

gcc/testsuite/ChangeLog:

	* lib/target-supports.exp (check_compile): Support -ftree-dump-xxx
	options.
	(check_effective_target_fold_memcpy): New function.
	(check_effective_target_fold_memcpy_2): Same.
	(check_effective_target_fold_memcpy_4): Same.
	(check_effective_target_fold_memcpy_8): Same.
	* c-c++-common/Warray-bounds-2.c: Include headers only if they exist.
	* c-c++-common/Warray-bounds-3.c: Make xfails conditional on target
	fold_memcpy.
	* c-c++-common/Wrestrict-2.c: Include headers only if they exist.
	* c-c++-common/Wrestrict.c: Make xfails conditional on target
	fold_memcpy.

Index: gcc/testsuite/lib/target-supports.exp
===================================================================
--- gcc/testsuite/lib/target-supports.exp	(revision 268082)
+++ gcc/testsuite/lib/target-supports.exp	(working copy)
@@ -82,6 +82,11 @@  proc check_compile {basename type contents args} {
 	    lappend options "additional_flags=-fdump-$type"
 	    set compile_type assembly
 	}
+	"tree-*" {
+	    set output ${basename}[pid].s
+	    lappend options "additional_flags=-fdump-$type"
+	    set compile_type assembly
+	}
     }
     set f [open $src "w"]
     puts $f $contents
@@ -95,6 +100,11 @@  proc check_compile {basename type contents args} {
     if [regexp "rtl-(.*)" $type dummy rtl_type] {
 	set scan_output "[glob $src.\[0-9\]\[0-9\]\[0-9\]r.$rtl_type]"
 	file delete $output
+    } else {
+	if [regexp "tree-(.*)" $type dummy tree_type] {
+	    set scan_output "[glob $src.\[0-9\]\[0-9\]\[0-9\]t.$tree_type]"
+	    file delete $output
+	}
     }
 
     # Restore additional_sources.
@@ -9048,6 +9058,44 @@  proc check_effective_target_autoincdec { } {
     return 0
 }
 
+# Return 1 if the target folds memcpy calls with sizes of count bytes.
+# The folding is done by the middle-end but targets have the ability
+# to control the maximum size or to disable it altogether.
+proc check_effective_target_fold_memcpy { count } {
+    set result [eval check_compile fold_memcpy tree-optimized {
+	"void test_fold_memcpy (void *d, const void *s) { __builtin_memcpy (d, s, $count); }"
+    } "-O2" ]
+    set lines [lindex $result 0]
+    set output [lindex $result 1]
+    set match 1
+
+    set file [open "$output" ]
+    set contents [read $file]
+    close $file
+
+    if { [ regexp "__builtin_memcpy" $contents] } {
+	# Not folded.
+	set match 0
+    }
+    remote_file build delete $output
+    return $match
+}
+
+# Return 1 if the target folds memcpy calls with sizes of 2.
+proc check_effective_target_fold_memcpy_2 { } {
+    return [check_effective_target_fold_memcpy { 2 }]
+}
+
+# Return 1 if the target folds memcpy calls with sizes of 4.
+proc check_effective_target_fold_memcpy_4 { } {
+    return [check_effective_target_fold_memcpy { 4 }]
+}
+
+# Return 1 if the target folds memcpy calls with sizes of 8.
+proc check_effective_target_fold_memcpy_8 { } {
+    return [check_effective_target_fold_memcpy { 8 }]
+}
+
 # Return 1 if the target has support for stack probing designed
 # to avoid stack-clash style attacks.
 #
Index: gcc/testsuite/c-c++-common/Warray-bounds-2.c
===================================================================
--- gcc/testsuite/c-c++-common/Warray-bounds-2.c	(revision 268082)
+++ gcc/testsuite/c-c++-common/Warray-bounds-2.c	(working copy)
@@ -8,13 +8,28 @@ 
    { dg-do compile }
    { dg-options "-O2 -Warray-bounds -Wno-stringop-overflow" } */
 
-#include <stddef.h>
-#include <string.h>
+#if __has_include (<stddef.h>)
+#  include <stddef.h>
+#else
+/* For cross-compilers.  */
+typedef __PTRDIFF_TYPE__   ptrdiff_t;
+typedef __SIZE_TYPE__      size_t;
+#endif
 
-#undef memcpy
-#undef strcpy
-#undef strncpy
+#if __has_include (<string.h>)
+#  include <string.h>
+#  undef memcpy
+#  undef strcat
+#  undef strcpy
+#  undef strncpy
+#else
+extern void* memcpy (void*, const void*, size_t);
+extern char* strcat (char*, const char*);
+extern char* strcpy (char*, const char*);
+extern char* strncpy (char*, const char*, size_t);
+#endif
 
+
 #define MAX  (__SIZE_MAX__ / 2)
 
 void sink (void*);
Index: gcc/testsuite/c-c++-common/Warray-bounds-3.c
===================================================================
--- gcc/testsuite/c-c++-common/Warray-bounds-3.c	(revision 268082)
+++ gcc/testsuite/c-c++-common/Warray-bounds-3.c	(working copy)
@@ -158,7 +158,7 @@  void test_memcpy_overflow (char *d, const char *s,
      but known access size is detected.  This works except with small
      sizes that are powers of 2 due to bug .  */
   T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 1);
-  T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 2);  /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 2 accessing array " "bug " { xfail *-*-* } } */
+  T (char, 1, arr + SR (DIFF_MAX - 1, DIFF_MAX), s, 2);  /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 2 accessing array " "bug " { xfail fold_memcpy_2 } } */
   T (char, 1, arr + SR (DIFF_MAX - 2, DIFF_MAX), s, 3);  /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 3 accessing array " "memcpy" } */
   T (char, 1, arr + SR (DIFF_MAX - 4, DIFF_MAX), s, 5);  /* { dg-warning "pointer overflow between offset \\\[\[0-9\]+, \[0-9\]+] and size 5 accessing array " "memcpy" } */
 }
Index: gcc/testsuite/c-c++-common/Wrestrict-2.c
===================================================================
--- gcc/testsuite/c-c++-common/Wrestrict-2.c	(revision 268082)
+++ gcc/testsuite/c-c++-common/Wrestrict-2.c	(working copy)
@@ -8,8 +8,30 @@ 
    { dg-do compile }
    { dg-options "-O2 -Wrestrict" } */
 
-#include <string.h>
+#if __has_include (<stddef.h>)
+#  include <stddef.h>
+#else
+/* For cross-compilers.  */
+typedef __PTRDIFF_TYPE__   ptrdiff_t;
+typedef __SIZE_TYPE__      size_t;
+#endif
 
+#if __has_include (<string.h>)
+#  include <string.h>
+#  undef memcpy
+#  undef strcat
+#  undef strcpy
+#  undef strncat
+#  undef strncpy
+#else
+extern void* memcpy (void*, const void*, size_t);
+extern char* strcat (char*, const char*);
+extern char* strcpy (char*, const char*);
+extern char* strncat (char*, const char*, size_t);
+extern char* strncpy (char*, const char*, size_t);
+#endif
+
+
 static void wrap_memcpy (void *d, const void *s, size_t n)
 {
   memcpy (d, s, n);   /* { dg-warning "accessing 2 bytes at offsets 0 and 1 overlaps 1 byte at offset 1" "memcpy" } */
Index: gcc/testsuite/c-c++-common/Wrestrict.c
===================================================================
--- gcc/testsuite/c-c++-common/Wrestrict.c	(revision 268082)
+++ gcc/testsuite/c-c++-common/Wrestrict.c	(working copy)
@@ -53,8 +53,11 @@  void test_memcpy_cst (void *d, const void *s)
 
   T (a, a, 0);
 
-  /* This isn't detected because memcpy calls with small power-of-2 sizes
-     are intentionally folded into safe copies equivalent to memmove.
+  /* This isn't detected because memcpy calls with size of 1 are
+     intentionally folded into safe copies equivalent to memmove,
+     regardless of the target (larger power-of-2 copies may or
+     may not be folded depending on the target -- see fold_memcpy_4
+     below, for example).
      It's marked xfail only because there is value in detecting such
      invalid calls for portability, and as a reminder of why it isn't
      diagnosed.  */
@@ -192,7 +195,7 @@  void test_memcpy_range (char *d, size_t sz)
   T (a + ir, a, 2);
   T (a + ir, a, 3);
   /* The following fails because the size is a small power of 2.  */
-  T (a + ir, a, 4);               /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps between 1 and 2 bytes at offset \\\[3, 2]" "memcpy" { xfail *-*-*} } */
+  T (a + ir, a, 4);               /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps between 1 and 2 bytes at offset \(\\\[3, 2]|\\\[2, 3]\)" "pr79220" { xfail fold_memcpy_4 } } */
   T (a + ir, a, 5);               /* { dg-warning "accessing 5 bytes at offsets \\\[2, 3] and 0 overlaps between 2 and 3 bytes at offset \\\[2, 3]" "memcpy" } */
 
   T (d + ir, d, 0);
@@ -199,12 +202,12 @@  void test_memcpy_range (char *d, size_t sz)
   T (d + ir, d, 1);
   T (d + ir, d, 2);
   T (d + ir, d, 3);
-  T (d + ir, d, 4);               /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps 1 byte at offset 3" "bug 79220" { xfail *-*-* } } */
+  T (d + ir, d, 4);               /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps between 1 and 2 bytes at offset \\\[2, 3]" "pr79220" { xfail fold_memcpy_4 } } */
   T (d + ir, d, 5);               /* { dg-warning "accessing 5 bytes at offsets \\\[2, 3] and 0 overlaps between 2 and 3 bytes at offset \\\[2, 3]" "memcpy" } */
 
   /* Because the size is constant and a power of 2 the following is
      folded too early to detect the overlap.  */
-  T (d + ir, d, 4);               /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps 2 byte at offset 2" "memcpy" { xfail *-*-* } } */
+  T (d + ir, d, 4);               /* { dg-warning "accessing 4 bytes at offsets \\\[2, 3] and 0 overlaps between 1 and 2 bytes at offset \\\[2, 3]" "pr79220" { xfail fold_memcpy_4 } } */
   T (d + ir, d, 5);               /* { dg-warning "accessing 5 bytes at offsets \\\[2, 3] and 0 overlaps between 2 and 3 bytes at offset \\\[2, 3]" "memcpy" } */
 
   /* Exercise the full range of size_t.  */