public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
@ 2021-10-11  2:47 Kewen.Lin
  2021-10-11 15:30 ` Segher Boessenkool
  0 siblings, 1 reply; 29+ messages in thread
From: Kewen.Lin @ 2021-10-11  2:47 UTC (permalink / raw)
  To: GCC Patches; +Cc: Segher Boessenkool, David Edelsohn, Bill Schmidt, Hongtao Liu

Hi,

As PR102658 shows, commit r12-4240 enables vectorization at O2,
some cases need to be adjusted accordingly for rs6000 port.

- For target specific test cases, this adds -fno-tree-vectorize
to retain original test points, otherwise vectorization can
make some expected scalar instructions gone or generate some
unexpected instructions for vector construction.

- For generic test cases, it follows the existing suggested
practice with necessary target/xfail selector.

Tested with expected results on powerpc64le-linux-gnu and
powerpc64-linux-gnu.

Is it ok for trunk?

BR,
Kewen
-----
gcc/testsuite/ChangeLog:

	PR testsuite/102658
	* c-c++-common/Wstringop-overflow-2.c: Adjust for rs6000 port.
	* g++.dg/warn/Wuninitialized-13.C: Likewise.
	* gcc.dg/Warray-parameter-3.c: Likewise.
	* gcc.dg/Wstringop-overflow-21.c: Likewise.
	* gcc.dg/Wstringop-overflow-68.c: Likewise.
	* gcc.dg/Wstringop-overflow-76.c: Likewise.
	* gcc.target/powerpc/dform-1.c: Adjust as vectorization enabled at O2.
	* gcc.target/powerpc/dform-2.c: Likewise.
	* gcc.target/powerpc/pr80510-2.c: Likewise.

---

diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
index 7d29b5f48c7..5d83caddc4e 100644
--- a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
+++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
@@ -221,10 +221,10 @@ void ga1_1 (void)
   a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
   a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }

-  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* powerpc*-*-* } } }
   a.a[0] = 0;
-  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
-  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* powerpc*-*-* } } }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* powerpc*-*-* } } }
   sink (&a);
 }

@@ -320,10 +320,10 @@ void ga1i_1 (void)
   a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow" }
   a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow" }

-  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* powerpc*-*-* } } }
   a.a[0] = 1;
-  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
-  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* powerpc*-*-* } } }
+  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* powerpc*-*-* } } }
   sink (&a);
 }

diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-13.C b/gcc/testsuite/g++.dg/warn/Wuninitialized-13.C
index 210e74c3c3b..4ad897a6486 100644
--- a/gcc/testsuite/g++.dg/warn/Wuninitialized-13.C
+++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-13.C
@@ -5,7 +5,7 @@
 struct shared_count {
   shared_count () { }
   shared_count (shared_count &r)
-    : pi (r.pi) { }     // { dg-warning "\\\[-Wuninitialized" "" { xfail { i?86-*-* x86_64-*-* } } }
+    : pi (r.pi) { }     // { dg-warning "\\\[-Wuninitialized" "" { xfail { i?86-*-* x86_64-*-* powerpc*-*-* } } }
   int pi;
 };

diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3.c b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
index e8a269c85c6..f7404be8742 100644
--- a/gcc/testsuite/gcc.dg/Warray-parameter-3.c
+++ b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
@@ -77,7 +77,7 @@ gia3 (int a[3])
 __attribute__ ((noipa)) void
 gcas3 (char a[static 3])
 {
-  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* powerpc*-*-* } } }
   a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
 }

diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
index d88bde9c740..2db6a52b22b 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
@@ -23,10 +23,10 @@ void test_store_zero_length (int i)
 {
   char a[3];
   struct S0 *p = (struct S0*)a;
-  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* powerpc*-*-* } } }
   p->b[0] = 0;
   p->b[1] = 1;                      // { dg-bogus "\\\[-Wstringop-overflow" }
-  p->b[2] = 2;                      // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  p->b[2] = 2;                      // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* powerpc*-*-* } } }
   p->b[i] = 2;
   sink (p);
 }
@@ -50,10 +50,10 @@ void test_store_flexarray (int i)
 {
   char a[3];
   struct Sx *p = (struct Sx*)a;
-  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* powerpc*-*-* } } }
   p->b[0] = 0;
   p->b[1] = 1;                      // { dg-bogus "\\\[-Wstringop-overflow" }
-  p->b[2] = 1;                      // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  p->b[2] = 1;                      // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* powerpc*-*-* } } }
   p->b[i] = 2;
   sink (p);
 }
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
index 09df0004991..02afe486f8a 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
@@ -58,10 +58,10 @@ void warn_comp_lit_zero (void)
 void warn_comp_lit (void)
 {
   *(AC2*)a1 = Ac2;      // { dg-warning "writing 2 bytes into a region of size 1" "pr101475" { xfail *-*-* } }
-  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 2" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
-  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 3" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
-  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 4" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
-  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 7" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
+  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 2" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* powerpc*-*-* } } } }
+  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 3" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* powerpc*-*-* } } } }
+  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 4" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* powerpc*-*-* } } } }
+  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 7" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* powerpc*-*-* } } } }
   *(AC16*)a15 = Ac16;   // { dg-warning "writing 16 bytes into a region of size 15" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
 }

diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
index 0c7b53ccc0b..e66794d59c9 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
@@ -27,10 +27,10 @@ void max_a3_a5 (int i)
      by its own warning independently of -Wstringop-overflow.  */
   char *d = MAX (p, q);

-  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "" { target { i?86-*-* x86_64-*-* } } }
+  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "" { target { i?86-*-* x86_64-*-* powerpc*-*-* } } }
   d[3] = 0;
   d[4] = 0;
-  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
+  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* powerpc*-*-* } } }
 }


@@ -44,10 +44,10 @@ void max_b6_b4 (int i)
   char *q = b4 + i;
   char *d = MAX (p, q);

-  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "" { target { i?86-*-* x86_64-*-* } } }
+  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "" { target { i?86-*-* x86_64-*-* powerpc*-*-* } } }
   d[4] = 0;
   d[5] = 0;
-  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
+  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* powerpc*-*-* } } }
 }


@@ -82,7 +82,7 @@ void max_d8_p (char *q, int i)
 struct A3_5
 {
   char a3[3];  // { dg-message "at offset 3 into destination object 'a3' of size 3" "pr??????" { xfail *-*-* } }
-  char a5[5];  // { dg-message "at offset 5 into destination object 'a5' of size 5" "note" { xfail { i?86-*-* x86_64-*-* } } }
+  char a5[5];  // { dg-message "at offset 5 into destination object 'a5' of size 5" "note" { xfail { i?86-*-* x86_64-*-* powerpc*-*-* } } }
 };

 void max_A3_A5 (int i, struct A3_5 *pa3_5)
@@ -95,14 +95,14 @@ void max_A3_A5 (int i, struct A3_5 *pa3_5)
   d[2] = 0;
   d[3] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "pr??????" { xfail *-*-* } }
   d[4] = 0;
-  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
+  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* powerpc*-*-* }  } }
 }


 struct B4_B6
 {
   char b4[4];
-  char b6[6];       // { dg-message "at offset \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6" "note" { xfail { i?86-*-* x86_64-*-* } } }
+  char b6[6];       // { dg-message "at offset \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6" "note" { xfail { i?86-*-* x86_64-*-* powerpc*-*-* } } }
 };

 void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
@@ -114,7 +114,7 @@ void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
   d[3] = 0;
   d[4] = 0;
   d[5] = 0;
-  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
+  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* powerpc*-*-* } } }
 }


diff --git a/gcc/testsuite/gcc.target/powerpc/dform-1.c b/gcc/testsuite/gcc.target/powerpc/dform-1.c
index fac39230fd6..1a0b0cf4c34 100644
--- a/gcc/testsuite/gcc.target/powerpc/dform-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/dform-1.c
@@ -1,6 +1,8 @@
 /* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
 /* { dg-require-effective-target powerpc_p9vector_ok } */
-/* { dg-options "-mpower9-vector -O2" } */
+/* Now O2 enables vectorization by default, which makes expected scalar
+   loads gone, so simply disable it.  */
+/* { dg-options "-mpower9-vector -O2 -fno-tree-vectorize" } */

 #ifndef TYPE
 #define TYPE double
diff --git a/gcc/testsuite/gcc.target/powerpc/dform-2.c b/gcc/testsuite/gcc.target/powerpc/dform-2.c
index 994733071e7..cc91f55b82d 100644
--- a/gcc/testsuite/gcc.target/powerpc/dform-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/dform-2.c
@@ -1,6 +1,8 @@
 /* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
 /* { dg-require-effective-target powerpc_p9vector_ok } */
-/* { dg-options "-mpower9-vector -O2" } */
+/* Now O2 enables vectorization by default, which generates unexpected float
+   conversion for vector construction, so simply disable it.  */
+/* { dg-options "-mpower9-vector -O2 -fno-tree-vectorize" } */

 #ifndef TYPE
 #define TYPE float
diff --git a/gcc/testsuite/gcc.target/powerpc/pr80510-2.c b/gcc/testsuite/gcc.target/powerpc/pr80510-2.c
index f85e005be64..d041d967c8b 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr80510-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr80510-2.c
@@ -1,7 +1,9 @@
 /* { dg-do compile { target { powerpc*-*-* } } } */
 /* { dg-skip-if "" { powerpc*-*-darwin* } } */
 /* { dg-require-effective-target powerpc_p8vector_ok } */
-/* { dg-options "-mdejagnu-cpu=power8 -O2" } */
+/* Now O2 enables vectorization by default, which generates unexpected VSR
+   to GPR movement for vector construction, so simply disable it.  */
+/* { dg-options "-mdejagnu-cpu=power8 -O2 -fno-tree-vectorize" } */

 /* Make sure that STXSSPX is generated for float scalars in Altivec registers
    on power7 instead of moving the value to a FPR register and doing a X-FORM

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
  2021-10-11  2:47 [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658] Kewen.Lin
@ 2021-10-11 15:30 ` Segher Boessenkool
  2021-10-11 16:23   ` Martin Sebor
  0 siblings, 1 reply; 29+ messages in thread
From: Segher Boessenkool @ 2021-10-11 15:30 UTC (permalink / raw)
  To: Kewen.Lin; +Cc: GCC Patches, David Edelsohn, Bill Schmidt, Hongtao Liu

Hi!

On Mon, Oct 11, 2021 at 10:47:00AM +0800, Kewen.Lin wrote:
> As PR102658 shows, commit r12-4240 enables vectorization at O2,
> some cases need to be adjusted accordingly for rs6000 port.
> 
> - For target specific test cases, this adds -fno-tree-vectorize
> to retain original test points, otherwise vectorization can
> make some expected scalar instructions gone or generate some
> unexpected instructions for vector construction.

Ah good choice.

> - For generic test cases, it follows the existing suggested
> practice with necessary target/xfail selector.

Not such a great choice.  Many of those tests do not make sense with
vectorisation enabled.  This should have been thought about, in some
cases resulting in not running the test with vectorisation enabled, and
in some cases duplicating the test, once with and once without
vectorisation.

But you are just following established practice, so :-)

> -  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> +  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* powerpc*-*-* } } }

I don't know if powerpc*-*-* is the correct choice in all these cases.
Sometimes it might have to be powerpc*-*-linux* or similar.  We'll find
out :-)

(An xfail causes XPASS if the test does *not* fail).

> +/* Now O2 enables vectorization by default, which generates unexpected float
> +   conversion for vector construction, so simply disable it.  */

It is good to see these comments.  I love puzzles, but not in the
testsuite! :-)

Okay for trunk.  Thanks!


Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
  2021-10-11 15:30 ` Segher Boessenkool
@ 2021-10-11 16:23   ` Martin Sebor
  2021-10-11 17:43     ` Segher Boessenkool
  0 siblings, 1 reply; 29+ messages in thread
From: Martin Sebor @ 2021-10-11 16:23 UTC (permalink / raw)
  To: Segher Boessenkool, Kewen.Lin
  Cc: Bill Schmidt, Hongtao Liu, GCC Patches, David Edelsohn

On 10/11/21 9:30 AM, Segher Boessenkool wrote:
> Hi!
> 
> On Mon, Oct 11, 2021 at 10:47:00AM +0800, Kewen.Lin wrote:
>> As PR102658 shows, commit r12-4240 enables vectorization at O2,
>> some cases need to be adjusted accordingly for rs6000 port.
>>
>> - For target specific test cases, this adds -fno-tree-vectorize
>> to retain original test points, otherwise vectorization can
>> make some expected scalar instructions gone or generate some
>> unexpected instructions for vector construction.
> 
> Ah good choice.
> 
>> - For generic test cases, it follows the existing suggested
>> practice with necessary target/xfail selector.
> 
> Not such a great choice.  Many of those tests do not make sense with
> vectorisation enabled.  This should have been thought about, in some
> cases resulting in not running the test with vectorisation enabled, and
> in some cases duplicating the test, once with and once without
> vectorisation.

The tests detect bugs that are present both with and without
vetctorization, so they should pass both ways.  That they don't
tells us that that the warnings need work (they were written with
an assumption that doesn't hold anymore).  We need to track that
work somehow, but simply xfailing them without making a record
of what underlying problem the xfails correspond to isn't the best
way.  In my experience, what works well is opening a bug for each
distinct limitation (if one doesn't already exist) and adding
a reference to it as a comment to the xfail.

> 
> But you are just following established practice, so :-)
> 
>> -  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
>> +  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* powerpc*-*-* } } }

As I mentioned in the bug, when adding xfails for regressions
please be sure to reference the bug that tracks the underlying
root cause.  There may be multiple problems, and we need to
identify what it is in each instance.  As the author of
the tests I can help with that but not if I'm not in the loop
on these changes (it would seem prudent to get the author's
thoughts on such sweeping changes to their work).

I discussed one of these failures with Hongtao in detail at
the time autovectorization was being enabled and made the same
request then but I didn't realize the problem was so pervasive.

In addition, the target-specific conditionals in the xfails are
going to be difficult to maintain.  It might be okay for one or
two in a single test but for so many we need a better solution
than that.  If autovectorization is only enabled for a subset
of targets then a solution might be to add a new DejagGNU test
for it and conditionalize the xfails on it.

Martin

> 
> I don't know if powerpc*-*-* is the correct choice in all these cases.
> Sometimes it might have to be powerpc*-*-linux* or similar.  We'll find
> out :-)
> 
> (An xfail causes XPASS if the test does *not* fail).
> 
>> +/* Now O2 enables vectorization by default, which generates unexpected float
>> +   conversion for vector construction, so simply disable it.  */
> 
> It is good to see these comments.  I love puzzles, but not in the
> testsuite! :-)
> 
> Okay for trunk.  Thanks!
> 
> 
> Segher
> 


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
  2021-10-11 16:23   ` Martin Sebor
@ 2021-10-11 17:43     ` Segher Boessenkool
  2021-10-11 20:07       ` Martin Sebor
  0 siblings, 1 reply; 29+ messages in thread
From: Segher Boessenkool @ 2021-10-11 17:43 UTC (permalink / raw)
  To: Martin Sebor
  Cc: Kewen.Lin, Bill Schmidt, Hongtao Liu, GCC Patches, David Edelsohn

On Mon, Oct 11, 2021 at 10:23:03AM -0600, Martin Sebor wrote:
> On 10/11/21 9:30 AM, Segher Boessenkool wrote:
> >On Mon, Oct 11, 2021 at 10:47:00AM +0800, Kewen.Lin wrote:
> >>- For generic test cases, it follows the existing suggested
> >>practice with necessary target/xfail selector.
> >
> >Not such a great choice.  Many of those tests do not make sense with
> >vectorisation enabled.  This should have been thought about, in some
> >cases resulting in not running the test with vectorisation enabled, and
> >in some cases duplicating the test, once with and once without
> >vectorisation.
> 
> The tests detect bugs that are present both with and without
> vetctorization, so they should pass both ways.

Then it should be tested both ways!  This is my point.

> That they don't
> tells us that that the warnings need work (they were written with
> an assumption that doesn't hold anymore).

They were written in world A.  In world B many things behave
differently.  Transplanting the testcases from A to B without any extra
analysis will not test what the testcases wanted to test, and possibly
nothing at all anymore.

> We need to track that
> work somehow, but simply xfailing them without making a record
> of what underlying problem the xfails correspond to isn't the best
> way.  In my experience, what works well is opening a bug for each
> distinct limitation (if one doesn't already exist) and adding
> a reference to it as a comment to the xfail.

Probably, yes.

> >But you are just following established practice, so :-)

I also am okay with this.  If it was decided x86 does not have to deal
with these (generic!) problems, then why should we do other people's
work?

> >>-  struct A1 a = { 0, { 1 } };   // { dg-warning 
> >>"\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> >>+  struct A1 a = { 0, { 1 } };   // { dg-warning 
> >>"\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* powerpc*-*-* 
> >>} } }
> 
> As I mentioned in the bug, when adding xfails for regressions
> please be sure to reference the bug that tracks the underlying
> root cause.]

You are saying this to whoever added that x86 xfail I hope.

> There may be multiple problems, and we need to
> identify what it is in each instance.  As the author of
> the tests I can help with that but not if I'm not in the loop
> on these changes (it would seem prudent to get the author's
> thoughts on such sweeping changes to their work).

Yup.

> I discussed one of these failures with Hongtao in detail at
> the time autovectorization was being enabled and made the same
> request then but I didn't realize the problem was so pervasive.
> 
> In addition, the target-specific conditionals in the xfails are
> going to be difficult to maintain.

It is a cop-out.  Especially because it makes no comment why it is
xfailed (which should *always* be explained!)

> It might be okay for one or
> two in a single test but for so many we need a better solution
> than that.  If autovectorization is only enabled for a subset
> of targets then a solution might be to add a new DejagGNU test
> for it and conditionalize the xfails on it.

That, combined with duplicating these tests and still testing the
-fno-vectorization situation properly.  Those tests tested something.
With vectorisation enabled they might no longer test that same thing,
especially if the test fails now!

Thanks,


Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
  2021-10-11 17:43     ` Segher Boessenkool
@ 2021-10-11 20:07       ` Martin Sebor
  2021-10-12  2:31         ` Hongtao Liu
  2021-10-12 18:11         ` [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658] Segher Boessenkool
  0 siblings, 2 replies; 29+ messages in thread
From: Martin Sebor @ 2021-10-11 20:07 UTC (permalink / raw)
  To: Segher Boessenkool, Hongtao Liu
  Cc: Kewen.Lin, Bill Schmidt, GCC Patches, David Edelsohn

On 10/11/21 11:43 AM, Segher Boessenkool wrote:
> On Mon, Oct 11, 2021 at 10:23:03AM -0600, Martin Sebor wrote:
>> On 10/11/21 9:30 AM, Segher Boessenkool wrote:
>>> On Mon, Oct 11, 2021 at 10:47:00AM +0800, Kewen.Lin wrote:
>>>> - For generic test cases, it follows the existing suggested
>>>> practice with necessary target/xfail selector.
>>>
>>> Not such a great choice.  Many of those tests do not make sense with
>>> vectorisation enabled.  This should have been thought about, in some
>>> cases resulting in not running the test with vectorisation enabled, and
>>> in some cases duplicating the test, once with and once without
>>> vectorisation.
>>
>> The tests detect bugs that are present both with and without
>> vetctorization, so they should pass both ways.
> 
> Then it should be tested both ways!  This is my point.

Agreed.  (Most warnings are tested with just one set of options,
but it's becoming apparent that the middle end ones should be
exercised more extensively.)

> 
>> That they don't
>> tells us that that the warnings need work (they were written with
>> an assumption that doesn't hold anymore).
> 
> They were written in world A.  In world B many things behave
> differently.  Transplanting the testcases from A to B without any extra
> analysis will not test what the testcases wanted to test, and possibly
> nothing at all anymore.

Absolutely.

> 
>> We need to track that
>> work somehow, but simply xfailing them without making a record
>> of what underlying problem the xfails correspond to isn't the best
>> way.  In my experience, what works well is opening a bug for each
>> distinct limitation (if one doesn't already exist) and adding
>> a reference to it as a comment to the xfail.
> 
> Probably, yes.
> 
>>> But you are just following established practice, so :-)
> 
> I also am okay with this.  If it was decided x86 does not have to deal
> with these (generic!) problems, then why should we do other people's
> work?

I don't know that anything was decided.  I think those changes
were made in haste, and (as you noted in your review of these
updates to them), were incomplete (missing comments referencing
the underlying bugs or limitations).  Now that we've noticed it
we should try to fix it.  I'm not expecting you (or Kwen) to do
other people's work, but it would help to let them/us know that
there is work for us to do.  I only noticed the problem by luck.

>>>> -  struct A1 a = { 0, { 1 } };   // { dg-warning
>>>> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
>>>> +  struct A1 a = { 0, { 1 } };   // { dg-warning
>>>> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* powerpc*-*-*
>>>> } } }
>>
>> As I mentioned in the bug, when adding xfails for regressions
>> please be sure to reference the bug that tracks the underlying
>> root cause.]
> 
> You are saying this to whoever added that x86 xfail I hope.

In general it's an appeal to both authors and reviewers of such
changes.  Here, it's mostly for Hongtao who apparently added all
these undocumented xfails.

>> There may be multiple problems, and we need to
>> identify what it is in each instance.  As the author of
>> the tests I can help with that but not if I'm not in the loop
>> on these changes (it would seem prudent to get the author's
>> thoughts on such sweeping changes to their work).
> 
> Yup.
> 
>> I discussed one of these failures with Hongtao in detail at
>> the time autovectorization was being enabled and made the same
>> request then but I didn't realize the problem was so pervasive.
>>
>> In addition, the target-specific conditionals in the xfails are
>> going to be difficult to maintain.
> 
> It is a cop-out.  Especially because it makes no comment why it is
> xfailed (which should *always* be explained!)
> 
>> It might be okay for one or
>> two in a single test but for so many we need a better solution
>> than that.  If autovectorization is only enabled for a subset
>> of targets then a solution might be to add a new DejagGNU test
>> for it and conditionalize the xfails on it.
> 
> That, combined with duplicating these tests and still testing the
> -fno-vectorization situation properly.  Those tests tested something.
> With vectorisation enabled they might no longer test that same thing,
> especially if the test fails now!

Right.  The original autovectorization change was made either
without a full analysis of its impact on the affected warnings,
or its impact wasn't adequately captured (either in the xfails
comments or by opening bugs for them).  Now that we know about
this we should try to fix it.  The first step toward that is
to review the xfailed test cases and for each add a comment with
the bug that captures its root cause.

Hongtao, please let me know if you are going to work on that.

Martin

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
  2021-10-11 20:07       ` Martin Sebor
@ 2021-10-12  2:31         ` Hongtao Liu
  2021-10-12 15:49           ` Martin Sebor
  2021-10-12 18:11         ` [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658] Segher Boessenkool
  1 sibling, 1 reply; 29+ messages in thread
From: Hongtao Liu @ 2021-10-12  2:31 UTC (permalink / raw)
  To: Martin Sebor
  Cc: Segher Boessenkool, Hongtao Liu, GCC Patches, Bill Schmidt,
	David Edelsohn

On Tue, Oct 12, 2021 at 4:08 AM Martin Sebor via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> On 10/11/21 11:43 AM, Segher Boessenkool wrote:
> > On Mon, Oct 11, 2021 at 10:23:03AM -0600, Martin Sebor wrote:
> >> On 10/11/21 9:30 AM, Segher Boessenkool wrote:
> >>> On Mon, Oct 11, 2021 at 10:47:00AM +0800, Kewen.Lin wrote:
> >>>> - For generic test cases, it follows the existing suggested
> >>>> practice with necessary target/xfail selector.
> >>>
> >>> Not such a great choice.  Many of those tests do not make sense with
> >>> vectorisation enabled.  This should have been thought about, in some
> >>> cases resulting in not running the test with vectorisation enabled, and
> >>> in some cases duplicating the test, once with and once without
> >>> vectorisation.
> >>
> >> The tests detect bugs that are present both with and without
> >> vetctorization, so they should pass both ways.
> >
> > Then it should be tested both ways!  This is my point.
>
> Agreed.  (Most warnings are tested with just one set of options,
> but it's becoming apparent that the middle end ones should be
> exercised more extensively.)
>
> >
> >> That they don't
> >> tells us that that the warnings need work (they were written with
> >> an assumption that doesn't hold anymore).
> >
> > They were written in world A.  In world B many things behave
> > differently.  Transplanting the testcases from A to B without any extra
> > analysis will not test what the testcases wanted to test, and possibly
> > nothing at all anymore.
>
> Absolutely.
>
> >
> >> We need to track that
> >> work somehow, but simply xfailing them without making a record
> >> of what underlying problem the xfails correspond to isn't the best
> >> way.  In my experience, what works well is opening a bug for each
> >> distinct limitation (if one doesn't already exist) and adding
> >> a reference to it as a comment to the xfail.
> >
> > Probably, yes.
> >
> >>> But you are just following established practice, so :-)
> >
> > I also am okay with this.  If it was decided x86 does not have to deal
> > with these (generic!) problems, then why should we do other people's
> > work?
>
> I don't know that anything was decided.  I think those changes
> were made in haste, and (as you noted in your review of these
> updates to them), were incomplete (missing comments referencing
> the underlying bugs or limitations).  Now that we've noticed it
> we should try to fix it.  I'm not expecting you (or Kwen) to do
> other people's work, but it would help to let them/us know that
> there is work for us to do.  I only noticed the problem by luck.
>
> >>>> -  struct A1 a = { 0, { 1 } };   // { dg-warning
> >>>> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> >>>> +  struct A1 a = { 0, { 1 } };   // { dg-warning
> >>>> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* powerpc*-*-*
> >>>> } } }
> >>
> >> As I mentioned in the bug, when adding xfails for regressions
> >> please be sure to reference the bug that tracks the underlying
> >> root cause.]
> >
> > You are saying this to whoever added that x86 xfail I hope.
>
> In general it's an appeal to both authors and reviewers of such
> changes.  Here, it's mostly for Hongtao who apparently added all
> these undocumented xfails.
>
> >> There may be multiple problems, and we need to
> >> identify what it is in each instance.  As the author of
> >> the tests I can help with that but not if I'm not in the loop
> >> on these changes (it would seem prudent to get the author's
> >> thoughts on such sweeping changes to their work).
> >
> > Yup.
> >
> >> I discussed one of these failures with Hongtao in detail at
> >> the time autovectorization was being enabled and made the same
> >> request then but I didn't realize the problem was so pervasive.
> >>
> >> In addition, the target-specific conditionals in the xfails are
> >> going to be difficult to maintain.
> >
> > It is a cop-out.  Especially because it makes no comment why it is
> > xfailed (which should *always* be explained!)
> >
> >> It might be okay for one or
> >> two in a single test but for so many we need a better solution
> >> than that.  If autovectorization is only enabled for a subset
> >> of targets then a solution might be to add a new DejagGNU test
> >> for it and conditionalize the xfails on it.
> >
> > That, combined with duplicating these tests and still testing the
> > -fno-vectorization situation properly.  Those tests tested something.
> > With vectorisation enabled they might no longer test that same thing,
> > especially if the test fails now!
>
> Right.  The original autovectorization change was made either
> without a full analysis of its impact on the affected warnings,
> or its impact wasn't adequately captured (either in the xfails
> comments or by opening bugs for them).  Now that we know about
> this we should try to fix it.  The first step toward that is
> to review the xfailed test cases and for each add a comment with
> the bug that captures its root cause.
>
> Hongtao, please let me know if you are going to work on that.
I will make a copy of the tests to test the -fno-tree-vectorize
scenario(the original test).
For the xfails, they're analyzed and recorded in pr102462/pr102697,
sorry for not adding comments to them.
The root causes for those xfails are divided into 2 categories:

1. All accesses are out of bound, and after vectorization, there are
some warnings missing.(Because there is only 1 access after
vectorization, 2 accesses w/o vectorization, and diagnostic is based
on access).
2. Part of accesses are inbound, part of accesses are out of bound,
and after vectorization, the warning goes from out of bound line to
inbound line.

for pr102697, it looks like the testcase is not well written.
>
> Martin



-- 
BR,
Hongtao

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
  2021-10-12  2:31         ` Hongtao Liu
@ 2021-10-12 15:49           ` Martin Sebor
  2021-10-12 16:18             ` Segher Boessenkool
  2021-10-13  3:34             ` Hongtao Liu
  0 siblings, 2 replies; 29+ messages in thread
From: Martin Sebor @ 2021-10-12 15:49 UTC (permalink / raw)
  To: Hongtao Liu
  Cc: Segher Boessenkool, Hongtao Liu, GCC Patches, Bill Schmidt,
	David Edelsohn

On 10/11/21 8:31 PM, Hongtao Liu wrote:
> On Tue, Oct 12, 2021 at 4:08 AM Martin Sebor via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
>>
>> On 10/11/21 11:43 AM, Segher Boessenkool wrote:
>>> On Mon, Oct 11, 2021 at 10:23:03AM -0600, Martin Sebor wrote:
>>>> On 10/11/21 9:30 AM, Segher Boessenkool wrote:
>>>>> On Mon, Oct 11, 2021 at 10:47:00AM +0800, Kewen.Lin wrote:
>>>>>> - For generic test cases, it follows the existing suggested
>>>>>> practice with necessary target/xfail selector.
>>>>>
>>>>> Not such a great choice.  Many of those tests do not make sense with
>>>>> vectorisation enabled.  This should have been thought about, in some
>>>>> cases resulting in not running the test with vectorisation enabled, and
>>>>> in some cases duplicating the test, once with and once without
>>>>> vectorisation.
>>>>
>>>> The tests detect bugs that are present both with and without
>>>> vetctorization, so they should pass both ways.
>>>
>>> Then it should be tested both ways!  This is my point.
>>
>> Agreed.  (Most warnings are tested with just one set of options,
>> but it's becoming apparent that the middle end ones should be
>> exercised more extensively.)
>>
>>>
>>>> That they don't
>>>> tells us that that the warnings need work (they were written with
>>>> an assumption that doesn't hold anymore).
>>>
>>> They were written in world A.  In world B many things behave
>>> differently.  Transplanting the testcases from A to B without any extra
>>> analysis will not test what the testcases wanted to test, and possibly
>>> nothing at all anymore.
>>
>> Absolutely.
>>
>>>
>>>> We need to track that
>>>> work somehow, but simply xfailing them without making a record
>>>> of what underlying problem the xfails correspond to isn't the best
>>>> way.  In my experience, what works well is opening a bug for each
>>>> distinct limitation (if one doesn't already exist) and adding
>>>> a reference to it as a comment to the xfail.
>>>
>>> Probably, yes.
>>>
>>>>> But you are just following established practice, so :-)
>>>
>>> I also am okay with this.  If it was decided x86 does not have to deal
>>> with these (generic!) problems, then why should we do other people's
>>> work?
>>
>> I don't know that anything was decided.  I think those changes
>> were made in haste, and (as you noted in your review of these
>> updates to them), were incomplete (missing comments referencing
>> the underlying bugs or limitations).  Now that we've noticed it
>> we should try to fix it.  I'm not expecting you (or Kwen) to do
>> other people's work, but it would help to let them/us know that
>> there is work for us to do.  I only noticed the problem by luck.
>>
>>>>>> -  struct A1 a = { 0, { 1 } };   // { dg-warning
>>>>>> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
>>>>>> +  struct A1 a = { 0, { 1 } };   // { dg-warning
>>>>>> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* powerpc*-*-*
>>>>>> } } }
>>>>
>>>> As I mentioned in the bug, when adding xfails for regressions
>>>> please be sure to reference the bug that tracks the underlying
>>>> root cause.]
>>>
>>> You are saying this to whoever added that x86 xfail I hope.
>>
>> In general it's an appeal to both authors and reviewers of such
>> changes.  Here, it's mostly for Hongtao who apparently added all
>> these undocumented xfails.
>>
>>>> There may be multiple problems, and we need to
>>>> identify what it is in each instance.  As the author of
>>>> the tests I can help with that but not if I'm not in the loop
>>>> on these changes (it would seem prudent to get the author's
>>>> thoughts on such sweeping changes to their work).
>>>
>>> Yup.
>>>
>>>> I discussed one of these failures with Hongtao in detail at
>>>> the time autovectorization was being enabled and made the same
>>>> request then but I didn't realize the problem was so pervasive.
>>>>
>>>> In addition, the target-specific conditionals in the xfails are
>>>> going to be difficult to maintain.
>>>
>>> It is a cop-out.  Especially because it makes no comment why it is
>>> xfailed (which should *always* be explained!)
>>>
>>>> It might be okay for one or
>>>> two in a single test but for so many we need a better solution
>>>> than that.  If autovectorization is only enabled for a subset
>>>> of targets then a solution might be to add a new DejagGNU test
>>>> for it and conditionalize the xfails on it.
>>>
>>> That, combined with duplicating these tests and still testing the
>>> -fno-vectorization situation properly.  Those tests tested something.
>>> With vectorisation enabled they might no longer test that same thing,
>>> especially if the test fails now!
>>
>> Right.  The original autovectorization change was made either
>> without a full analysis of its impact on the affected warnings,
>> or its impact wasn't adequately captured (either in the xfails
>> comments or by opening bugs for them).  Now that we know about
>> this we should try to fix it.  The first step toward that is
>> to review the xfailed test cases and for each add a comment with
>> the bug that captures its root cause.
>>
>> Hongtao, please let me know if you are going to work on that.
> I will make a copy of the tests to test the -fno-tree-vectorize
> scenario(the original test).
> For the xfails, they're analyzed and recorded in pr102462/pr102697,
> sorry for not adding comments to them.

Thanks for raising pr102697!  It captures the essence of the bug
that's masked by the vectorization of the invalid store.  This is
due to the hack I pointed to in the discussion below:

https://gcc.gnu.org/pipermail/gcc-patches/2021-September/580172.html

> The root causes for those xfails are divided into 2 categories:
> 
> 1. All accesses are out of bound, and after vectorization, there are
> some warnings missing.(Because there is only 1 access after
> vectorization, 2 accesses w/o vectorization, and diagnostic is based
> on access).

If these involve -Wstringop-overflow for accesses that span
multiple subobjects, as in writing past the end of one member
and over the following member, then that would be due to
pr102697 (the hack above).

> 2. Part of accesses are inbound, part of accesses are out of bound,
> and after vectorization, the warning goes from out of bound line to
> inbound line.

Right, this is the issue we talked about during the review of
your patch, and I think is captured in the test case in comment
#4 on pr102462.

> 
> for pr102697, it looks like the testcase is not well written.

The test case is correct.  I've added my comments to the PR
and confirmed it as a GCC 12 regression.  (I may not have
the time to fix it for GCC 12 but I will plan to get to it
for GCC 13 unless someone beats me to it.)

I think it might be helpful to open a bug just for case (2)
and reference it in all the corresponding xfails.

pr102462 talks about three distinct cases and mentions
-Warray-bounds as well as -Wstringop-overflow.  It's not clear
from it exactly which of the three cases it's meant to be about.

There is also an undocumented xfail in
g++.dg/warn/Wuninitialized-13.C.  It should get its own bug
even if the essence of the problem is the same (the warning
doesn't share an implementation with -Warray-bounds or
-Wstringop-overflow so a fix will most likely need to be
separate from one for the other bugs).

Coming back to the xfail conditionals, do you think you'll
be able to put together some target-supports magic so they
don't have to enumerate all the affected targets?

Martin

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
  2021-10-12 15:49           ` Martin Sebor
@ 2021-10-12 16:18             ` Segher Boessenkool
  2021-10-12 17:15               ` Martin Sebor
  2021-10-13  3:34             ` Hongtao Liu
  1 sibling, 1 reply; 29+ messages in thread
From: Segher Boessenkool @ 2021-10-12 16:18 UTC (permalink / raw)
  To: Martin Sebor
  Cc: Hongtao Liu, Hongtao Liu, GCC Patches, Bill Schmidt, David Edelsohn

Hi!

On Tue, Oct 12, 2021 at 09:49:19AM -0600, Martin Sebor wrote:
> Coming back to the xfail conditionals, do you think you'll
> be able to put together some target-supports magic so they
> don't have to enumerate all the affected targets?

There should only be an xfail if we do not expect to be able to fix the
bug causing this any time soon.  There shouldn't be one here, not yet
anyway.

Other than that: yes, and one you have such a selector, just dg-require
it (or its inverse) for this test, don't xfail the test (if this is
expected and correct behaviour).


Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
  2021-10-12 16:18             ` Segher Boessenkool
@ 2021-10-12 17:15               ` Martin Sebor
  2021-10-12 17:45                 ` Jeff Law
  2021-10-12 18:01                 ` Segher Boessenkool
  0 siblings, 2 replies; 29+ messages in thread
From: Martin Sebor @ 2021-10-12 17:15 UTC (permalink / raw)
  To: Segher Boessenkool
  Cc: Hongtao Liu, Hongtao Liu, GCC Patches, Bill Schmidt, David Edelsohn

On 10/12/21 10:18 AM, Segher Boessenkool wrote:
> Hi!
> 
> On Tue, Oct 12, 2021 at 09:49:19AM -0600, Martin Sebor wrote:
>> Coming back to the xfail conditionals, do you think you'll
>> be able to put together some target-supports magic so they
>> don't have to enumerate all the affected targets?
> 
> There should only be an xfail if we do not expect to be able to fix the
> bug causing this any time soon.  There shouldn't be one here, not yet
> anyway.
> 
> Other than that: yes, and one you have such a selector, just dg-require
> it (or its inverse) for this test, don't xfail the test (if this is
> expected and correct behaviour).

My sense is that fixing all the fallout from the vectorization
change is going to be delicate and time-consuming work.  With
the end of stage 1 just about a month away I'm not too optimistic
how much of it I'll be able to get it done before then.  Depending
on how intrusive the fixes turn out to be it may or may not be
suitable in stage 3.

Based on pr102706 that Jeff reported for the regressions in his
automated tester, it also sounds like the test failures are spread
out across a multitude of targets.  In addition, it doesn't look
like the targets are all the same in all the tests.  Enumerating
the targets that correspond to each test failure would be like
playing the proverbial Whac-A-Mole.

That makes me think we do need some such selector rather soon.

The failing test cases are a subset of all the cases exercised
by the tests.  We don't want to conditionally enable/disable
the whole tests just for the few failing cases (if that's what
you were suggesting by dg-require).  So we need to apply
the selector to individual dg-warning and dg-bogus directives
in these tests.

Martin

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
  2021-10-12 17:15               ` Martin Sebor
@ 2021-10-12 17:45                 ` Jeff Law
  2021-10-12 18:01                 ` Segher Boessenkool
  1 sibling, 0 replies; 29+ messages in thread
From: Jeff Law @ 2021-10-12 17:45 UTC (permalink / raw)
  To: Martin Sebor, Segher Boessenkool
  Cc: Bill Schmidt, GCC Patches, Hongtao Liu, David Edelsohn



On 10/12/2021 11:15 AM, Martin Sebor via Gcc-patches wrote:
> On 10/12/21 10:18 AM, Segher Boessenkool wrote:
>> Hi!
>>
>> On Tue, Oct 12, 2021 at 09:49:19AM -0600, Martin Sebor wrote:
>>> Coming back to the xfail conditionals, do you think you'll
>>> be able to put together some target-supports magic so they
>>> don't have to enumerate all the affected targets?
>>
>> There should only be an xfail if we do not expect to be able to fix the
>> bug causing this any time soon.  There shouldn't be one here, not yet
>> anyway.
>>
>> Other than that: yes, and one you have such a selector, just dg-require
>> it (or its inverse) for this test, don't xfail the test (if this is
>> expected and correct behaviour).
>
> My sense is that fixing all the fallout from the vectorization
> change is going to be delicate and time-consuming work.  With
> the end of stage 1 just about a month away I'm not too optimistic
> how much of it I'll be able to get it done before then.  Depending
> on how intrusive the fixes turn out to be it may or may not be
> suitable in stage 3.
>
> Based on pr102706 that Jeff reported for the regressions in his
> automated tester, it also sounds like the test failures are spread
> out across a multitude of targets.  In addition, it doesn't look
> like the targets are all the same in all the tests.  Enumerating
> the targets that correspond to each test failure would be like
> playing the proverbial Whac-A-Mole.
There'll be some degree of whac-a-mole.  But it likely isn't every 
target.   I'm still evaluating that when I have a few minutes to look at 
a given target.

jeff


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
  2021-10-12 17:15               ` Martin Sebor
  2021-10-12 17:45                 ` Jeff Law
@ 2021-10-12 18:01                 ` Segher Boessenkool
  1 sibling, 0 replies; 29+ messages in thread
From: Segher Boessenkool @ 2021-10-12 18:01 UTC (permalink / raw)
  To: Martin Sebor
  Cc: Hongtao Liu, Hongtao Liu, GCC Patches, Bill Schmidt, David Edelsohn

On Tue, Oct 12, 2021 at 11:15:51AM -0600, Martin Sebor wrote:
> On 10/12/21 10:18 AM, Segher Boessenkool wrote:
> >On Tue, Oct 12, 2021 at 09:49:19AM -0600, Martin Sebor wrote:
> >>Coming back to the xfail conditionals, do you think you'll
> >>be able to put together some target-supports magic so they
> >>don't have to enumerate all the affected targets?
> >
> >There should only be an xfail if we do not expect to be able to fix the
> >bug causing this any time soon.  There shouldn't be one here, not yet
> >anyway.
> >
> >Other than that: yes, and one you have such a selector, just dg-require
> >it (or its inverse) for this test, don't xfail the test (if this is
> >expected and correct behaviour).
> 
> My sense is that fixing all the fallout from the vectorization
> change is going to be delicate and time-consuming work.  With
> the end of stage 1 just about a month away I'm not too optimistic
> how much of it I'll be able to get it done before then.  Depending
> on how intrusive the fixes turn out to be it may or may not be
> suitable in stage 3.

Some it will be suitable for stage4, even (testsuite-only changes for
example).

> Based on pr102706 that Jeff reported for the regressions in his
> automated tester, it also sounds like the test failures are spread
> out across a multitude of targets.  In addition, it doesn't look
> like the targets are all the same in all the tests.  Enumerating
> the targets that correspond to each test failure would be like
> playing the proverbial Whac-A-Mole.
> 
> That makes me think we do need some such selector rather soon.

Yes.

> The failing test cases are a subset of all the cases exercised
> by the tests.  We don't want to conditionally enable/disable
> the whole tests just for the few failing cases (if that's what
> you were suggesting by dg-require).

I mean that the tests should not be done on targets where those tests
do not make sense.

> So we need to apply
> the selector to individual dg-warning and dg-bogus directives
> in these tests.

Some of those tests should not be run with -fvectorize at all, imo.
You *want* to limit things a lot, for detail tests.


Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
  2021-10-11 20:07       ` Martin Sebor
  2021-10-12  2:31         ` Hongtao Liu
@ 2021-10-12 18:11         ` Segher Boessenkool
  1 sibling, 0 replies; 29+ messages in thread
From: Segher Boessenkool @ 2021-10-12 18:11 UTC (permalink / raw)
  To: Martin Sebor
  Cc: Hongtao Liu, Kewen.Lin, Bill Schmidt, GCC Patches, David Edelsohn

On Mon, Oct 11, 2021 at 02:07:49PM -0600, Martin Sebor wrote:
> On 10/11/21 11:43 AM, Segher Boessenkool wrote:
> >I also am okay with this.  If it was decided x86 does not have to deal
> >with these (generic!) problems, then why should we do other people's
> >work?
> 
> I don't know that anything was decided.

It was approved though :-)  I don't know all history behind it.

> I think those changes
> were made in haste, and (as you noted in your review of these
> updates to them), were incomplete (missing comments referencing
> the underlying bugs or limitations).

Yeah.

> Now that we've noticed it
> we should try to fix it.  I'm not expecting you (or Kwen) to do
> other people's work, but it would help to let them/us know that
> there is work for us to do.  I only noticed the problem by luck.

There is still a month of stage 1 to go, and we are getting >50 new
fails every day.  Maybe once that dies down we can report anything :-(


Segher

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
  2021-10-12 15:49           ` Martin Sebor
  2021-10-12 16:18             ` Segher Boessenkool
@ 2021-10-13  3:34             ` Hongtao Liu
  2021-10-13  6:29               ` Hongtao Liu
  1 sibling, 1 reply; 29+ messages in thread
From: Hongtao Liu @ 2021-10-13  3:34 UTC (permalink / raw)
  To: Martin Sebor
  Cc: Segher Boessenkool, Hongtao Liu, GCC Patches, Bill Schmidt,
	David Edelsohn

On Tue, Oct 12, 2021 at 11:49 PM Martin Sebor <msebor@gmail.com> wrote:
>
> On 10/11/21 8:31 PM, Hongtao Liu wrote:
> > On Tue, Oct 12, 2021 at 4:08 AM Martin Sebor via Gcc-patches
> > <gcc-patches@gcc.gnu.org> wrote:
> >>
> >> On 10/11/21 11:43 AM, Segher Boessenkool wrote:
> >>> On Mon, Oct 11, 2021 at 10:23:03AM -0600, Martin Sebor wrote:
> >>>> On 10/11/21 9:30 AM, Segher Boessenkool wrote:
> >>>>> On Mon, Oct 11, 2021 at 10:47:00AM +0800, Kewen.Lin wrote:
> >>>>>> - For generic test cases, it follows the existing suggested
> >>>>>> practice with necessary target/xfail selector.
> >>>>>
> >>>>> Not such a great choice.  Many of those tests do not make sense with
> >>>>> vectorisation enabled.  This should have been thought about, in some
> >>>>> cases resulting in not running the test with vectorisation enabled, and
> >>>>> in some cases duplicating the test, once with and once without
> >>>>> vectorisation.
> >>>>
> >>>> The tests detect bugs that are present both with and without
> >>>> vetctorization, so they should pass both ways.
> >>>
> >>> Then it should be tested both ways!  This is my point.
> >>
> >> Agreed.  (Most warnings are tested with just one set of options,
> >> but it's becoming apparent that the middle end ones should be
> >> exercised more extensively.)
> >>
> >>>
> >>>> That they don't
> >>>> tells us that that the warnings need work (they were written with
> >>>> an assumption that doesn't hold anymore).
> >>>
> >>> They were written in world A.  In world B many things behave
> >>> differently.  Transplanting the testcases from A to B without any extra
> >>> analysis will not test what the testcases wanted to test, and possibly
> >>> nothing at all anymore.
> >>
> >> Absolutely.
> >>
> >>>
> >>>> We need to track that
> >>>> work somehow, but simply xfailing them without making a record
> >>>> of what underlying problem the xfails correspond to isn't the best
> >>>> way.  In my experience, what works well is opening a bug for each
> >>>> distinct limitation (if one doesn't already exist) and adding
> >>>> a reference to it as a comment to the xfail.
> >>>
> >>> Probably, yes.
> >>>
> >>>>> But you are just following established practice, so :-)
> >>>
> >>> I also am okay with this.  If it was decided x86 does not have to deal
> >>> with these (generic!) problems, then why should we do other people's
> >>> work?
> >>
> >> I don't know that anything was decided.  I think those changes
> >> were made in haste, and (as you noted in your review of these
> >> updates to them), were incomplete (missing comments referencing
> >> the underlying bugs or limitations).  Now that we've noticed it
> >> we should try to fix it.  I'm not expecting you (or Kwen) to do
> >> other people's work, but it would help to let them/us know that
> >> there is work for us to do.  I only noticed the problem by luck.
> >>
> >>>>>> -  struct A1 a = { 0, { 1 } };   // { dg-warning
> >>>>>> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> >>>>>> +  struct A1 a = { 0, { 1 } };   // { dg-warning
> >>>>>> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* powerpc*-*-*
> >>>>>> } } }
> >>>>
> >>>> As I mentioned in the bug, when adding xfails for regressions
> >>>> please be sure to reference the bug that tracks the underlying
> >>>> root cause.]
> >>>
> >>> You are saying this to whoever added that x86 xfail I hope.
> >>
> >> In general it's an appeal to both authors and reviewers of such
> >> changes.  Here, it's mostly for Hongtao who apparently added all
> >> these undocumented xfails.
> >>
> >>>> There may be multiple problems, and we need to
> >>>> identify what it is in each instance.  As the author of
> >>>> the tests I can help with that but not if I'm not in the loop
> >>>> on these changes (it would seem prudent to get the author's
> >>>> thoughts on such sweeping changes to their work).
> >>>
> >>> Yup.
> >>>
> >>>> I discussed one of these failures with Hongtao in detail at
> >>>> the time autovectorization was being enabled and made the same
> >>>> request then but I didn't realize the problem was so pervasive.
> >>>>
> >>>> In addition, the target-specific conditionals in the xfails are
> >>>> going to be difficult to maintain.
> >>>
> >>> It is a cop-out.  Especially because it makes no comment why it is
> >>> xfailed (which should *always* be explained!)
> >>>
> >>>> It might be okay for one or
> >>>> two in a single test but for so many we need a better solution
> >>>> than that.  If autovectorization is only enabled for a subset
> >>>> of targets then a solution might be to add a new DejagGNU test
> >>>> for it and conditionalize the xfails on it.
> >>>
> >>> That, combined with duplicating these tests and still testing the
> >>> -fno-vectorization situation properly.  Those tests tested something.
> >>> With vectorisation enabled they might no longer test that same thing,
> >>> especially if the test fails now!
> >>
> >> Right.  The original autovectorization change was made either
> >> without a full analysis of its impact on the affected warnings,
> >> or its impact wasn't adequately captured (either in the xfails
> >> comments or by opening bugs for them).  Now that we know about
> >> this we should try to fix it.  The first step toward that is
> >> to review the xfailed test cases and for each add a comment with
> >> the bug that captures its root cause.
> >>
> >> Hongtao, please let me know if you are going to work on that.
> > I will make a copy of the tests to test the -fno-tree-vectorize
> > scenario(the original test).
> > For the xfails, they're analyzed and recorded in pr102462/pr102697,
> > sorry for not adding comments to them.
>
> Thanks for raising pr102697!  It captures the essence of the bug
> that's masked by the vectorization of the invalid store.  This is
> due to the hack I pointed to in the discussion below:
>
> https://gcc.gnu.org/pipermail/gcc-patches/2021-September/580172.html
>
> > The root causes for those xfails are divided into 2 categories:
> >
> > 1. All accesses are out of bound, and after vectorization, there are
> > some warnings missing.(Because there is only 1 access after
> > vectorization, 2 accesses w/o vectorization, and diagnostic is based
> > on access).
>
> If these involve -Wstringop-overflow for accesses that span
> multiple subobjects, as in writing past the end of one member
> and over the following member, then that would be due to
> pr102697 (the hack above).
>
> > 2. Part of accesses are inbound, part of accesses are out of bound,
> > and after vectorization, the warning goes from out of bound line to
> > inbound line.
>
> Right, this is the issue we talked about during the review of
> your patch, and I think is captured in the test case in comment
> #4 on pr102462.
>
> >
> > for pr102697, it looks like the testcase is not well written.
>
> The test case is correct.  I've added my comments to the PR
> and confirmed it as a GCC 12 regression.  (I may not have
> the time to fix it for GCC 12 but I will plan to get to it
> for GCC 13 unless someone beats me to it.)
>
> I think it might be helpful to open a bug just for case (2)
> and reference it in all the corresponding xfails.
>
> pr102462 talks about three distinct cases and mentions
> -Warray-bounds as well as -Wstringop-overflow.  It's not clear
> from it exactly which of the three cases it's meant to be about.
>
> There is also an undocumented xfail in
> g++.dg/warn/Wuninitialized-13.C.  It should get its own bug
> even if the essence of the problem is the same (the warning
> doesn't share an implementation with -Warray-bounds or
> -Wstringop-overflow so a fix will most likely need to be
> separate from one for the other bugs).
>
> Coming back to the xfail conditionals, do you think you'll
> be able to put together some target-supports magic so they
> don't have to enumerate all the affected targets?
>
Those failure testcases(exposed by x86 part)can be extracted and
categorized into 3 below testcases.
Question is can we check vectorization ability in
dg-require-effective-target for those testcase?
If we can, we  can dynamically check whether each target supports this xfail.

foo is used for vector(2) char, foo1 vector(4) char, foo2 vector(2) short.

char p[4] __attribute__ ((aligned (4)));
void
foo ()
{
  p[0] = 1;
  p[1] = 2;
  p[2] = 3;
}

void
foo1 ()
{
  p[0] = 0;
  p[1] = 1;
  p[2] = 2;
  p[3] = 3;
}

void
foo2 (short* q)
{
  q[0] = 0;
  q[1] = 1;
}
> Martin




--
BR,
Hongtao

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
  2021-10-13  3:34             ` Hongtao Liu
@ 2021-10-13  6:29               ` Hongtao Liu
  2021-10-13  7:43                 ` Kewen.Lin
  0 siblings, 1 reply; 29+ messages in thread
From: Hongtao Liu @ 2021-10-13  6:29 UTC (permalink / raw)
  To: Martin Sebor
  Cc: Segher Boessenkool, Hongtao Liu, GCC Patches, Bill Schmidt,
	David Edelsohn

On Wed, Oct 13, 2021 at 11:34 AM Hongtao Liu <crazylht@gmail.com> wrote:
>
> On Tue, Oct 12, 2021 at 11:49 PM Martin Sebor <msebor@gmail.com> wrote:
> >
> > On 10/11/21 8:31 PM, Hongtao Liu wrote:
> > > On Tue, Oct 12, 2021 at 4:08 AM Martin Sebor via Gcc-patches
> > > <gcc-patches@gcc.gnu.org> wrote:
> > >>
> > >> On 10/11/21 11:43 AM, Segher Boessenkool wrote:
> > >>> On Mon, Oct 11, 2021 at 10:23:03AM -0600, Martin Sebor wrote:
> > >>>> On 10/11/21 9:30 AM, Segher Boessenkool wrote:
> > >>>>> On Mon, Oct 11, 2021 at 10:47:00AM +0800, Kewen.Lin wrote:
> > >>>>>> - For generic test cases, it follows the existing suggested
> > >>>>>> practice with necessary target/xfail selector.
> > >>>>>
> > >>>>> Not such a great choice.  Many of those tests do not make sense with
> > >>>>> vectorisation enabled.  This should have been thought about, in some
> > >>>>> cases resulting in not running the test with vectorisation enabled, and
> > >>>>> in some cases duplicating the test, once with and once without
> > >>>>> vectorisation.
> > >>>>
> > >>>> The tests detect bugs that are present both with and without
> > >>>> vetctorization, so they should pass both ways.
> > >>>
> > >>> Then it should be tested both ways!  This is my point.
> > >>
> > >> Agreed.  (Most warnings are tested with just one set of options,
> > >> but it's becoming apparent that the middle end ones should be
> > >> exercised more extensively.)
> > >>
> > >>>
> > >>>> That they don't
> > >>>> tells us that that the warnings need work (they were written with
> > >>>> an assumption that doesn't hold anymore).
> > >>>
> > >>> They were written in world A.  In world B many things behave
> > >>> differently.  Transplanting the testcases from A to B without any extra
> > >>> analysis will not test what the testcases wanted to test, and possibly
> > >>> nothing at all anymore.
> > >>
> > >> Absolutely.
> > >>
> > >>>
> > >>>> We need to track that
> > >>>> work somehow, but simply xfailing them without making a record
> > >>>> of what underlying problem the xfails correspond to isn't the best
> > >>>> way.  In my experience, what works well is opening a bug for each
> > >>>> distinct limitation (if one doesn't already exist) and adding
> > >>>> a reference to it as a comment to the xfail.
> > >>>
> > >>> Probably, yes.
> > >>>
> > >>>>> But you are just following established practice, so :-)
> > >>>
> > >>> I also am okay with this.  If it was decided x86 does not have to deal
> > >>> with these (generic!) problems, then why should we do other people's
> > >>> work?
> > >>
> > >> I don't know that anything was decided.  I think those changes
> > >> were made in haste, and (as you noted in your review of these
> > >> updates to them), were incomplete (missing comments referencing
> > >> the underlying bugs or limitations).  Now that we've noticed it
> > >> we should try to fix it.  I'm not expecting you (or Kwen) to do
> > >> other people's work, but it would help to let them/us know that
> > >> there is work for us to do.  I only noticed the problem by luck.
> > >>
> > >>>>>> -  struct A1 a = { 0, { 1 } };   // { dg-warning
> > >>>>>> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> > >>>>>> +  struct A1 a = { 0, { 1 } };   // { dg-warning
> > >>>>>> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* powerpc*-*-*
> > >>>>>> } } }
> > >>>>
> > >>>> As I mentioned in the bug, when adding xfails for regressions
> > >>>> please be sure to reference the bug that tracks the underlying
> > >>>> root cause.]
> > >>>
> > >>> You are saying this to whoever added that x86 xfail I hope.
> > >>
> > >> In general it's an appeal to both authors and reviewers of such
> > >> changes.  Here, it's mostly for Hongtao who apparently added all
> > >> these undocumented xfails.
> > >>
> > >>>> There may be multiple problems, and we need to
> > >>>> identify what it is in each instance.  As the author of
> > >>>> the tests I can help with that but not if I'm not in the loop
> > >>>> on these changes (it would seem prudent to get the author's
> > >>>> thoughts on such sweeping changes to their work).
> > >>>
> > >>> Yup.
> > >>>
> > >>>> I discussed one of these failures with Hongtao in detail at
> > >>>> the time autovectorization was being enabled and made the same
> > >>>> request then but I didn't realize the problem was so pervasive.
> > >>>>
> > >>>> In addition, the target-specific conditionals in the xfails are
> > >>>> going to be difficult to maintain.
> > >>>
> > >>> It is a cop-out.  Especially because it makes no comment why it is
> > >>> xfailed (which should *always* be explained!)
> > >>>
> > >>>> It might be okay for one or
> > >>>> two in a single test but for so many we need a better solution
> > >>>> than that.  If autovectorization is only enabled for a subset
> > >>>> of targets then a solution might be to add a new DejagGNU test
> > >>>> for it and conditionalize the xfails on it.
> > >>>
> > >>> That, combined with duplicating these tests and still testing the
> > >>> -fno-vectorization situation properly.  Those tests tested something.
> > >>> With vectorisation enabled they might no longer test that same thing,
> > >>> especially if the test fails now!
> > >>
> > >> Right.  The original autovectorization change was made either
> > >> without a full analysis of its impact on the affected warnings,
> > >> or its impact wasn't adequately captured (either in the xfails
> > >> comments or by opening bugs for them).  Now that we know about
> > >> this we should try to fix it.  The first step toward that is
> > >> to review the xfailed test cases and for each add a comment with
> > >> the bug that captures its root cause.
> > >>
> > >> Hongtao, please let me know if you are going to work on that.
> > > I will make a copy of the tests to test the -fno-tree-vectorize
> > > scenario(the original test).
> > > For the xfails, they're analyzed and recorded in pr102462/pr102697,
> > > sorry for not adding comments to them.
> >
> > Thanks for raising pr102697!  It captures the essence of the bug
> > that's masked by the vectorization of the invalid store.  This is
> > due to the hack I pointed to in the discussion below:
> >
> > https://gcc.gnu.org/pipermail/gcc-patches/2021-September/580172.html
> >
> > > The root causes for those xfails are divided into 2 categories:
> > >
> > > 1. All accesses are out of bound, and after vectorization, there are
> > > some warnings missing.(Because there is only 1 access after
> > > vectorization, 2 accesses w/o vectorization, and diagnostic is based
> > > on access).
> >
> > If these involve -Wstringop-overflow for accesses that span
> > multiple subobjects, as in writing past the end of one member
> > and over the following member, then that would be due to
> > pr102697 (the hack above).
> >
> > > 2. Part of accesses are inbound, part of accesses are out of bound,
> > > and after vectorization, the warning goes from out of bound line to
> > > inbound line.
> >
> > Right, this is the issue we talked about during the review of
> > your patch, and I think is captured in the test case in comment
> > #4 on pr102462.
> >
> > >
> > > for pr102697, it looks like the testcase is not well written.
> >
> > The test case is correct.  I've added my comments to the PR
> > and confirmed it as a GCC 12 regression.  (I may not have
> > the time to fix it for GCC 12 but I will plan to get to it
> > for GCC 13 unless someone beats me to it.)
> >
> > I think it might be helpful to open a bug just for case (2)
> > and reference it in all the corresponding xfails.
> >
> > pr102462 talks about three distinct cases and mentions
> > -Warray-bounds as well as -Wstringop-overflow.  It's not clear
> > from it exactly which of the three cases it's meant to be about.
> >
> > There is also an undocumented xfail in
> > g++.dg/warn/Wuninitialized-13.C.  It should get its own bug
> > even if the essence of the problem is the same (the warning
> > doesn't share an implementation with -Warray-bounds or
> > -Wstringop-overflow so a fix will most likely need to be
> > separate from one for the other bugs).
> >
> > Coming back to the xfail conditionals, do you think you'll
> > be able to put together some target-supports magic so they
> > don't have to enumerate all the affected targets?
> >
> Those failure testcases(exposed by x86 part)can be extracted and
> categorized into 3 below testcases.
> Question is can we check vectorization ability in
> dg-require-effective-target for those testcase?
> If we can, we  can dynamically check whether each target supports this xfail.
>
How about
+# Return true if vectorization of v2qi store is enabed.
+# Return zero if the desirable pattern isn't found.
+# It's used by Warray-bounds/Wstringop-overflow testcases which are
+# regressed by O2 vectorization, refer to PR102697/PR102462/PR102706
+proc check_vect_slp_v2qi_store_usage { } {
+    global tool
+
+    return [check_cached_effective_target slp_v2qi_store_usage {
+      set result [check_compile slp_v2qi_store_usage assembly {
+   char p[4] __attribute__ ((aligned (4)));
+   void
+   foo ()
+   {
+       p[0] = 1;
+       p[1] = 2;
+       p[2] = 3;
+   }
+      } "-O2 -fopt-info-all" ]
+
+      # Get compiler emitted messages and delete generated file.
+      set lines [lindex $result 0]
+      set output [lindex $result 1]
+      remote_file build delete $output
+
+      set pattern1 {optimized: basic block part vectorized using
[0-9]+ byte vectors}
+      set pattern2 {add new stmt: MEM <vector\(2\) char>}
+      # Capture the vectorized info of v2qi, set it to zero if not found.
+ if { ![regexp $pattern1 $lines whole val]
+      || ![regexp $pattern2 $lines whole val] } then {
+   set val 0
+      }
+
+      return $val
+    }]
+}
+
+# Return the true if target support vectorization of v2qi store.
+proc check_effective_target_vect_slp_v2qi_store { } {
+    return [expr { [check_vect_slp_v2qi_store_usage] != 0 }]
+}

similar for vect_slp_v4qi_store/vec_slp_v2hi_store, and add these
target selector to xfail/target cases.
> foo is used for vector(2) char, foo1 vector(4) char, foo2 vector(2) short.
>
> char p[4] __attribute__ ((aligned (4)));
> void
> foo ()
> {
>   p[0] = 1;
>   p[1] = 2;
>   p[2] = 3;
> }
>
> void
> foo1 ()
> {
>   p[0] = 0;
>   p[1] = 1;
>   p[2] = 2;
>   p[3] = 3;
> }
>
> void
> foo2 (short* q)
> {
>   q[0] = 0;
>   q[1] = 1;
> }
> > Martin
>
>
>
>
> --
> BR,
> Hongtao



-- 
BR,
Hongtao

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
  2021-10-13  6:29               ` Hongtao Liu
@ 2021-10-13  7:43                 ` Kewen.Lin
  2021-10-13 14:36                   ` Martin Sebor
  2021-10-14  7:11                   ` [PATCH] Adjust testcase for O2 vectorization liuhongt
  0 siblings, 2 replies; 29+ messages in thread
From: Kewen.Lin @ 2021-10-13  7:43 UTC (permalink / raw)
  To: Hongtao Liu
  Cc: Bill Schmidt, Hongtao Liu, GCC Patches, David Edelsohn,
	Segher Boessenkool, Martin Sebor

on 2021/10/13 下午2:29, Hongtao Liu via Gcc-patches wrote:
> On Wed, Oct 13, 2021 at 11:34 AM Hongtao Liu <crazylht@gmail.com> wrote:
>>
>> On Tue, Oct 12, 2021 at 11:49 PM Martin Sebor <msebor@gmail.com> wrote:
>>>
>>> On 10/11/21 8:31 PM, Hongtao Liu wrote:
>>>> On Tue, Oct 12, 2021 at 4:08 AM Martin Sebor via Gcc-patches
>>>> <gcc-patches@gcc.gnu.org> wrote:
>>>>>
>>>>> On 10/11/21 11:43 AM, Segher Boessenkool wrote:
>>>>>> On Mon, Oct 11, 2021 at 10:23:03AM -0600, Martin Sebor wrote:
>>>>>>> On 10/11/21 9:30 AM, Segher Boessenkool wrote:
>>>>>>>> On Mon, Oct 11, 2021 at 10:47:00AM +0800, Kewen.Lin wrote:
>>>>>>>>> - For generic test cases, it follows the existing suggested
>>>>>>>>> practice with necessary target/xfail selector.
>>>>>>>>
>>>>>>>> Not such a great choice.  Many of those tests do not make sense with
>>>>>>>> vectorisation enabled.  This should have been thought about, in some
>>>>>>>> cases resulting in not running the test with vectorisation enabled, and
>>>>>>>> in some cases duplicating the test, once with and once without
>>>>>>>> vectorisation.
>>>>>>>
>>>>>>> The tests detect bugs that are present both with and without
>>>>>>> vetctorization, so they should pass both ways.
>>>>>>
>>>>>> Then it should be tested both ways!  This is my point.
>>>>>
>>>>> Agreed.  (Most warnings are tested with just one set of options,
>>>>> but it's becoming apparent that the middle end ones should be
>>>>> exercised more extensively.)
>>>>>
>>>>>>
>>>>>>> That they don't
>>>>>>> tells us that that the warnings need work (they were written with
>>>>>>> an assumption that doesn't hold anymore).
>>>>>>
>>>>>> They were written in world A.  In world B many things behave
>>>>>> differently.  Transplanting the testcases from A to B without any extra
>>>>>> analysis will not test what the testcases wanted to test, and possibly
>>>>>> nothing at all anymore.
>>>>>
>>>>> Absolutely.
>>>>>
>>>>>>
>>>>>>> We need to track that
>>>>>>> work somehow, but simply xfailing them without making a record
>>>>>>> of what underlying problem the xfails correspond to isn't the best
>>>>>>> way.  In my experience, what works well is opening a bug for each
>>>>>>> distinct limitation (if one doesn't already exist) and adding
>>>>>>> a reference to it as a comment to the xfail.
>>>>>>
>>>>>> Probably, yes.
>>>>>>
>>>>>>>> But you are just following established practice, so :-)
>>>>>>
>>>>>> I also am okay with this.  If it was decided x86 does not have to deal
>>>>>> with these (generic!) problems, then why should we do other people's
>>>>>> work?
>>>>>
>>>>> I don't know that anything was decided.  I think those changes
>>>>> were made in haste, and (as you noted in your review of these
>>>>> updates to them), were incomplete (missing comments referencing
>>>>> the underlying bugs or limitations).  Now that we've noticed it
>>>>> we should try to fix it.  I'm not expecting you (or Kwen) to do
>>>>> other people's work, but it would help to let them/us know that
>>>>> there is work for us to do.  I only noticed the problem by luck.
>>>>>
>>>>>>>>> -  struct A1 a = { 0, { 1 } };   // { dg-warning
>>>>>>>>> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
>>>>>>>>> +  struct A1 a = { 0, { 1 } };   // { dg-warning
>>>>>>>>> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* powerpc*-*-*
>>>>>>>>> } } }
>>>>>>>
>>>>>>> As I mentioned in the bug, when adding xfails for regressions
>>>>>>> please be sure to reference the bug that tracks the underlying
>>>>>>> root cause.]
>>>>>>
>>>>>> You are saying this to whoever added that x86 xfail I hope.
>>>>>
>>>>> In general it's an appeal to both authors and reviewers of such
>>>>> changes.  Here, it's mostly for Hongtao who apparently added all
>>>>> these undocumented xfails.
>>>>>
>>>>>>> There may be multiple problems, and we need to
>>>>>>> identify what it is in each instance.  As the author of
>>>>>>> the tests I can help with that but not if I'm not in the loop
>>>>>>> on these changes (it would seem prudent to get the author's
>>>>>>> thoughts on such sweeping changes to their work).
>>>>>>
>>>>>> Yup.
>>>>>>
>>>>>>> I discussed one of these failures with Hongtao in detail at
>>>>>>> the time autovectorization was being enabled and made the same
>>>>>>> request then but I didn't realize the problem was so pervasive.
>>>>>>>
>>>>>>> In addition, the target-specific conditionals in the xfails are
>>>>>>> going to be difficult to maintain.
>>>>>>
>>>>>> It is a cop-out.  Especially because it makes no comment why it is
>>>>>> xfailed (which should *always* be explained!)
>>>>>>
>>>>>>> It might be okay for one or
>>>>>>> two in a single test but for so many we need a better solution
>>>>>>> than that.  If autovectorization is only enabled for a subset
>>>>>>> of targets then a solution might be to add a new DejagGNU test
>>>>>>> for it and conditionalize the xfails on it.
>>>>>>
>>>>>> That, combined with duplicating these tests and still testing the
>>>>>> -fno-vectorization situation properly.  Those tests tested something.
>>>>>> With vectorisation enabled they might no longer test that same thing,
>>>>>> especially if the test fails now!
>>>>>
>>>>> Right.  The original autovectorization change was made either
>>>>> without a full analysis of its impact on the affected warnings,
>>>>> or its impact wasn't adequately captured (either in the xfails
>>>>> comments or by opening bugs for them).  Now that we know about
>>>>> this we should try to fix it.  The first step toward that is
>>>>> to review the xfailed test cases and for each add a comment with
>>>>> the bug that captures its root cause.
>>>>>
>>>>> Hongtao, please let me know if you are going to work on that.
>>>> I will make a copy of the tests to test the -fno-tree-vectorize
>>>> scenario(the original test).
>>>> For the xfails, they're analyzed and recorded in pr102462/pr102697,
>>>> sorry for not adding comments to them.
>>>
>>> Thanks for raising pr102697!  It captures the essence of the bug
>>> that's masked by the vectorization of the invalid store.  This is
>>> due to the hack I pointed to in the discussion below:
>>>
>>> https://gcc.gnu.org/pipermail/gcc-patches/2021-September/580172.html
>>>
>>>> The root causes for those xfails are divided into 2 categories:
>>>>
>>>> 1. All accesses are out of bound, and after vectorization, there are
>>>> some warnings missing.(Because there is only 1 access after
>>>> vectorization, 2 accesses w/o vectorization, and diagnostic is based
>>>> on access).
>>>
>>> If these involve -Wstringop-overflow for accesses that span
>>> multiple subobjects, as in writing past the end of one member
>>> and over the following member, then that would be due to
>>> pr102697 (the hack above).
>>>
>>>> 2. Part of accesses are inbound, part of accesses are out of bound,
>>>> and after vectorization, the warning goes from out of bound line to
>>>> inbound line.
>>>
>>> Right, this is the issue we talked about during the review of
>>> your patch, and I think is captured in the test case in comment
>>> #4 on pr102462.
>>>
>>>>
>>>> for pr102697, it looks like the testcase is not well written.
>>>
>>> The test case is correct.  I've added my comments to the PR
>>> and confirmed it as a GCC 12 regression.  (I may not have
>>> the time to fix it for GCC 12 but I will plan to get to it
>>> for GCC 13 unless someone beats me to it.)
>>>
>>> I think it might be helpful to open a bug just for case (2)
>>> and reference it in all the corresponding xfails.
>>>
>>> pr102462 talks about three distinct cases and mentions
>>> -Warray-bounds as well as -Wstringop-overflow.  It's not clear
>>> from it exactly which of the three cases it's meant to be about.
>>>
>>> There is also an undocumented xfail in
>>> g++.dg/warn/Wuninitialized-13.C.  It should get its own bug
>>> even if the essence of the problem is the same (the warning
>>> doesn't share an implementation with -Warray-bounds or
>>> -Wstringop-overflow so a fix will most likely need to be
>>> separate from one for the other bugs).
>>>
>>> Coming back to the xfail conditionals, do you think you'll
>>> be able to put together some target-supports magic so they
>>> don't have to enumerate all the affected targets?
>>>
>> Those failure testcases(exposed by x86 part)can be extracted and
>> categorized into 3 below testcases.
>> Question is can we check vectorization ability in
>> dg-require-effective-target for those testcase?
>> If we can, we  can dynamically check whether each target supports this xfail.
>>
> How about
> +# Return true if vectorization of v2qi store is enabed.
> +# Return zero if the desirable pattern isn't found.
> +# It's used by Warray-bounds/Wstringop-overflow testcases which are
> +# regressed by O2 vectorization, refer to PR102697/PR102462/PR102706
> +proc check_vect_slp_v2qi_store_usage { } {
> +    global tool
> +
> +    return [check_cached_effective_target slp_v2qi_store_usage {
> +      set result [check_compile slp_v2qi_store_usage assembly {
> +   char p[4] __attribute__ ((aligned (4)));
> +   void
> +   foo ()
> +   {
> +       p[0] = 1;
> +       p[1] = 2;
> +       p[2] = 3;
> +   }
> +      } "-O2 -fopt-info-all" ]
> +
> +      # Get compiler emitted messages and delete generated file.
> +      set lines [lindex $result 0]
> +      set output [lindex $result 1]
> +      remote_file build delete $output
> +
> +      set pattern1 {optimized: basic block part vectorized using
> [0-9]+ byte vectors}
> +      set pattern2 {add new stmt: MEM <vector\(2\) char>}
> +      # Capture the vectorized info of v2qi, set it to zero if not found.
> + if { ![regexp $pattern1 $lines whole val]
> +      || ![regexp $pattern2 $lines whole val] } then {
> +   set val 0
> +      }
> +
> +      return $val
> +    }]
> +}
> +
> +# Return the true if target support vectorization of v2qi store.
> +proc check_effective_target_vect_slp_v2qi_store { } {
> +    return [expr { [check_vect_slp_v2qi_store_usage] != 0 }]
> +}
> 
> similar for vect_slp_v4qi_store/vec_slp_v2hi_store, and add these
> target selector to xfail/target cases.

Nice!  Thanks for doing this.  It seems we can have one general proc
check_vect_slp_store_usage, and pass the different arguments to it
according to v2qi, v4qi and v2hi.

And I assume all these kinds of test cases are simple, it won't have
the possibility that this pre-test says slp-ed while the actual case
says no when there are some other stmts affecting the profitability
evaluation.  Otherwise, we might have to force unlimited cost model
for both.

BR,
Kewen

>> foo is used for vector(2) char, foo1 vector(4) char, foo2 vector(2) short.
>>
>> char p[4] __attribute__ ((aligned (4)));
>> void
>> foo ()
>> {
>>   p[0] = 1;
>>   p[1] = 2;
>>   p[2] = 3;
>> }
>>
>> void
>> foo1 ()
>> {
>>   p[0] = 0;
>>   p[1] = 1;
>>   p[2] = 2;
>>   p[3] = 3;
>> }
>>
>> void
>> foo2 (short* q)
>> {
>>   q[0] = 0;
>>   q[1] = 1;
>> }
>>> Martin
>>
>>
>>
>>
>> --
>> BR,
>> Hongtao
> 
> 
> 


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658]
  2021-10-13  7:43                 ` Kewen.Lin
@ 2021-10-13 14:36                   ` Martin Sebor
  2021-10-14  7:11                   ` [PATCH] Adjust testcase for O2 vectorization liuhongt
  1 sibling, 0 replies; 29+ messages in thread
From: Martin Sebor @ 2021-10-13 14:36 UTC (permalink / raw)
  To: Kewen.Lin, Hongtao Liu
  Cc: Bill Schmidt, Hongtao Liu, GCC Patches, David Edelsohn,
	Segher Boessenkool

On 10/13/21 1:43 AM, Kewen.Lin wrote:
> on 2021/10/13 下午2:29, Hongtao Liu via Gcc-patches wrote:
>> On Wed, Oct 13, 2021 at 11:34 AM Hongtao Liu <crazylht@gmail.com> wrote:
>>>
>>> On Tue, Oct 12, 2021 at 11:49 PM Martin Sebor <msebor@gmail.com> wrote:
>>>>
>>>> On 10/11/21 8:31 PM, Hongtao Liu wrote:
>>>>> On Tue, Oct 12, 2021 at 4:08 AM Martin Sebor via Gcc-patches
>>>>> <gcc-patches@gcc.gnu.org> wrote:
>>>>>>
>>>>>> On 10/11/21 11:43 AM, Segher Boessenkool wrote:
>>>>>>> On Mon, Oct 11, 2021 at 10:23:03AM -0600, Martin Sebor wrote:
>>>>>>>> On 10/11/21 9:30 AM, Segher Boessenkool wrote:
>>>>>>>>> On Mon, Oct 11, 2021 at 10:47:00AM +0800, Kewen.Lin wrote:
>>>>>>>>>> - For generic test cases, it follows the existing suggested
>>>>>>>>>> practice with necessary target/xfail selector.
>>>>>>>>>
>>>>>>>>> Not such a great choice.  Many of those tests do not make sense with
>>>>>>>>> vectorisation enabled.  This should have been thought about, in some
>>>>>>>>> cases resulting in not running the test with vectorisation enabled, and
>>>>>>>>> in some cases duplicating the test, once with and once without
>>>>>>>>> vectorisation.
>>>>>>>>
>>>>>>>> The tests detect bugs that are present both with and without
>>>>>>>> vetctorization, so they should pass both ways.
>>>>>>>
>>>>>>> Then it should be tested both ways!  This is my point.
>>>>>>
>>>>>> Agreed.  (Most warnings are tested with just one set of options,
>>>>>> but it's becoming apparent that the middle end ones should be
>>>>>> exercised more extensively.)
>>>>>>
>>>>>>>
>>>>>>>> That they don't
>>>>>>>> tells us that that the warnings need work (they were written with
>>>>>>>> an assumption that doesn't hold anymore).
>>>>>>>
>>>>>>> They were written in world A.  In world B many things behave
>>>>>>> differently.  Transplanting the testcases from A to B without any extra
>>>>>>> analysis will not test what the testcases wanted to test, and possibly
>>>>>>> nothing at all anymore.
>>>>>>
>>>>>> Absolutely.
>>>>>>
>>>>>>>
>>>>>>>> We need to track that
>>>>>>>> work somehow, but simply xfailing them without making a record
>>>>>>>> of what underlying problem the xfails correspond to isn't the best
>>>>>>>> way.  In my experience, what works well is opening a bug for each
>>>>>>>> distinct limitation (if one doesn't already exist) and adding
>>>>>>>> a reference to it as a comment to the xfail.
>>>>>>>
>>>>>>> Probably, yes.
>>>>>>>
>>>>>>>>> But you are just following established practice, so :-)
>>>>>>>
>>>>>>> I also am okay with this.  If it was decided x86 does not have to deal
>>>>>>> with these (generic!) problems, then why should we do other people's
>>>>>>> work?
>>>>>>
>>>>>> I don't know that anything was decided.  I think those changes
>>>>>> were made in haste, and (as you noted in your review of these
>>>>>> updates to them), were incomplete (missing comments referencing
>>>>>> the underlying bugs or limitations).  Now that we've noticed it
>>>>>> we should try to fix it.  I'm not expecting you (or Kwen) to do
>>>>>> other people's work, but it would help to let them/us know that
>>>>>> there is work for us to do.  I only noticed the problem by luck.
>>>>>>
>>>>>>>>>> -  struct A1 a = { 0, { 1 } };   // { dg-warning
>>>>>>>>>> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
>>>>>>>>>> +  struct A1 a = { 0, { 1 } };   // { dg-warning
>>>>>>>>>> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* powerpc*-*-*
>>>>>>>>>> } } }
>>>>>>>>
>>>>>>>> As I mentioned in the bug, when adding xfails for regressions
>>>>>>>> please be sure to reference the bug that tracks the underlying
>>>>>>>> root cause.]
>>>>>>>
>>>>>>> You are saying this to whoever added that x86 xfail I hope.
>>>>>>
>>>>>> In general it's an appeal to both authors and reviewers of such
>>>>>> changes.  Here, it's mostly for Hongtao who apparently added all
>>>>>> these undocumented xfails.
>>>>>>
>>>>>>>> There may be multiple problems, and we need to
>>>>>>>> identify what it is in each instance.  As the author of
>>>>>>>> the tests I can help with that but not if I'm not in the loop
>>>>>>>> on these changes (it would seem prudent to get the author's
>>>>>>>> thoughts on such sweeping changes to their work).
>>>>>>>
>>>>>>> Yup.
>>>>>>>
>>>>>>>> I discussed one of these failures with Hongtao in detail at
>>>>>>>> the time autovectorization was being enabled and made the same
>>>>>>>> request then but I didn't realize the problem was so pervasive.
>>>>>>>>
>>>>>>>> In addition, the target-specific conditionals in the xfails are
>>>>>>>> going to be difficult to maintain.
>>>>>>>
>>>>>>> It is a cop-out.  Especially because it makes no comment why it is
>>>>>>> xfailed (which should *always* be explained!)
>>>>>>>
>>>>>>>> It might be okay for one or
>>>>>>>> two in a single test but for so many we need a better solution
>>>>>>>> than that.  If autovectorization is only enabled for a subset
>>>>>>>> of targets then a solution might be to add a new DejagGNU test
>>>>>>>> for it and conditionalize the xfails on it.
>>>>>>>
>>>>>>> That, combined with duplicating these tests and still testing the
>>>>>>> -fno-vectorization situation properly.  Those tests tested something.
>>>>>>> With vectorisation enabled they might no longer test that same thing,
>>>>>>> especially if the test fails now!
>>>>>>
>>>>>> Right.  The original autovectorization change was made either
>>>>>> without a full analysis of its impact on the affected warnings,
>>>>>> or its impact wasn't adequately captured (either in the xfails
>>>>>> comments or by opening bugs for them).  Now that we know about
>>>>>> this we should try to fix it.  The first step toward that is
>>>>>> to review the xfailed test cases and for each add a comment with
>>>>>> the bug that captures its root cause.
>>>>>>
>>>>>> Hongtao, please let me know if you are going to work on that.
>>>>> I will make a copy of the tests to test the -fno-tree-vectorize
>>>>> scenario(the original test).
>>>>> For the xfails, they're analyzed and recorded in pr102462/pr102697,
>>>>> sorry for not adding comments to them.
>>>>
>>>> Thanks for raising pr102697!  It captures the essence of the bug
>>>> that's masked by the vectorization of the invalid store.  This is
>>>> due to the hack I pointed to in the discussion below:
>>>>
>>>> https://gcc.gnu.org/pipermail/gcc-patches/2021-September/580172.html
>>>>
>>>>> The root causes for those xfails are divided into 2 categories:
>>>>>
>>>>> 1. All accesses are out of bound, and after vectorization, there are
>>>>> some warnings missing.(Because there is only 1 access after
>>>>> vectorization, 2 accesses w/o vectorization, and diagnostic is based
>>>>> on access).
>>>>
>>>> If these involve -Wstringop-overflow for accesses that span
>>>> multiple subobjects, as in writing past the end of one member
>>>> and over the following member, then that would be due to
>>>> pr102697 (the hack above).
>>>>
>>>>> 2. Part of accesses are inbound, part of accesses are out of bound,
>>>>> and after vectorization, the warning goes from out of bound line to
>>>>> inbound line.
>>>>
>>>> Right, this is the issue we talked about during the review of
>>>> your patch, and I think is captured in the test case in comment
>>>> #4 on pr102462.
>>>>
>>>>>
>>>>> for pr102697, it looks like the testcase is not well written.
>>>>
>>>> The test case is correct.  I've added my comments to the PR
>>>> and confirmed it as a GCC 12 regression.  (I may not have
>>>> the time to fix it for GCC 12 but I will plan to get to it
>>>> for GCC 13 unless someone beats me to it.)
>>>>
>>>> I think it might be helpful to open a bug just for case (2)
>>>> and reference it in all the corresponding xfails.
>>>>
>>>> pr102462 talks about three distinct cases and mentions
>>>> -Warray-bounds as well as -Wstringop-overflow.  It's not clear
>>>> from it exactly which of the three cases it's meant to be about.
>>>>
>>>> There is also an undocumented xfail in
>>>> g++.dg/warn/Wuninitialized-13.C.  It should get its own bug
>>>> even if the essence of the problem is the same (the warning
>>>> doesn't share an implementation with -Warray-bounds or
>>>> -Wstringop-overflow so a fix will most likely need to be
>>>> separate from one for the other bugs).
>>>>
>>>> Coming back to the xfail conditionals, do you think you'll
>>>> be able to put together some target-supports magic so they
>>>> don't have to enumerate all the affected targets?
>>>>
>>> Those failure testcases(exposed by x86 part)can be extracted and
>>> categorized into 3 below testcases.
>>> Question is can we check vectorization ability in
>>> dg-require-effective-target for those testcase?
>>> If we can, we  can dynamically check whether each target supports this xfail.
>>>
>> How about
>> +# Return true if vectorization of v2qi store is enabed.
>> +# Return zero if the desirable pattern isn't found.
>> +# It's used by Warray-bounds/Wstringop-overflow testcases which are
>> +# regressed by O2 vectorization, refer to PR102697/PR102462/PR102706
>> +proc check_vect_slp_v2qi_store_usage { } {
>> +    global tool
>> +
>> +    return [check_cached_effective_target slp_v2qi_store_usage {
>> +      set result [check_compile slp_v2qi_store_usage assembly {
>> +   char p[4] __attribute__ ((aligned (4)));
>> +   void
>> +   foo ()
>> +   {
>> +       p[0] = 1;
>> +       p[1] = 2;
>> +       p[2] = 3;
>> +   }
>> +      } "-O2 -fopt-info-all" ]
>> +
>> +      # Get compiler emitted messages and delete generated file.
>> +      set lines [lindex $result 0]
>> +      set output [lindex $result 1]
>> +      remote_file build delete $output
>> +
>> +      set pattern1 {optimized: basic block part vectorized using
>> [0-9]+ byte vectors}
>> +      set pattern2 {add new stmt: MEM <vector\(2\) char>}
>> +      # Capture the vectorized info of v2qi, set it to zero if not found.
>> + if { ![regexp $pattern1 $lines whole val]
>> +      || ![regexp $pattern2 $lines whole val] } then {
>> +   set val 0
>> +      }
>> +
>> +      return $val
>> +    }]
>> +}
>> +
>> +# Return the true if target support vectorization of v2qi store.
>> +proc check_effective_target_vect_slp_v2qi_store { } {
>> +    return [expr { [check_vect_slp_v2qi_store_usage] != 0 }]
>> +}
>>
>> similar for vect_slp_v4qi_store/vec_slp_v2hi_store, and add these
>> target selector to xfail/target cases.
> 
> Nice!  Thanks for doing this.  It seems we can have one general proc
> check_vect_slp_store_usage, and pass the different arguments to it
> according to v2qi, v4qi and v2hi.

Yes, thanks for your help!  If this approach is sufficiently
reliable it's great.  My own thought was to check the output
of -Q --help=optimizers looking for vectorization being enabled:

$ gcc -O2 -S -Wall -Q --help=optimizers -xc - </dev/null | grep vector
   -ftree-loop-vectorize       		[enabled]
   -ftree-slp-vectorize        		[enabled]
   -ftree-vectorize            		[disabled]

Whereas with GCC 11:

   -ftree-loop-vectorize       		[disabled]
   -ftree-slp-vectorize        		[disabled]
   -ftree-vectorize            		

Martin

> 
> And I assume all these kinds of test cases are simple, it won't have
> the possibility that this pre-test says slp-ed while the actual case
> says no when there are some other stmts affecting the profitability
> evaluation.  Otherwise, we might have to force unlimited cost model
> for both.
> 
> BR,
> Kewen
> 
>>> foo is used for vector(2) char, foo1 vector(4) char, foo2 vector(2) short.
>>>
>>> char p[4] __attribute__ ((aligned (4)));
>>> void
>>> foo ()
>>> {
>>>    p[0] = 1;
>>>    p[1] = 2;
>>>    p[2] = 3;
>>> }
>>>
>>> void
>>> foo1 ()
>>> {
>>>    p[0] = 0;
>>>    p[1] = 1;
>>>    p[2] = 2;
>>>    p[3] = 3;
>>> }
>>>
>>> void
>>> foo2 (short* q)
>>> {
>>>    q[0] = 0;
>>>    q[1] = 1;
>>> }
>>>> Martin
>>>
>>>
>>>
>>>
>>> --
>>> BR,
>>> Hongtao
>>
>>
>>
> 


^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH] Adjust testcase for O2 vectorization.
  2021-10-13  7:43                 ` Kewen.Lin
  2021-10-13 14:36                   ` Martin Sebor
@ 2021-10-14  7:11                   ` liuhongt
  2021-10-14  7:52                     ` Bernhard Reutner-Fischer
                                       ` (2 more replies)
  1 sibling, 3 replies; 29+ messages in thread
From: liuhongt @ 2021-10-14  7:11 UTC (permalink / raw)
  To: gcc-patches

Hi Kewen:
  Cound you help to verify if this patch fix those regressions
for rs6000 port.

As discussed in [1], this patch add xfail/target selector to those
testcases, also make a copy of them so that they can be tested w/o
vectorization.

Newly added xfail/target selectors are used to check the vectorization
capability of continuous byte/double bytes storage, these scenarios
are exactly the part of the testcases that regressed after O2
vectorization.

[1] https://gcc.gnu.org/pipermail/gcc-patches/2021-October/581456.html.

gcc/testsuite/ChangeLog

	PR middle-end/102722
	PR middle-end/102697
	PR middle-end/102462
	PR middle-end/102706
	* c-c++-common/Wstringop-overflow-2.c: Adjust testcase with new
	xfail/target selector.
	* gcc.dg/Warray-bounds-51.c: Ditto.
	* gcc.dg/Warray-parameter-3.c: Ditto.
	* gcc.dg/Wstringop-overflow-14.c: Ditto.
	* gcc.dg/Wstringop-overflow-21.c: Ditto.
	* gcc.dg/Wstringop-overflow-68.c: Ditto.
	* gcc.dg/Wstringop-overflow-76.c: Ditto.
	* gcc.dg/Warray-bounds-48.c: Ditto.
	* lib/target-supports.exp (check_vect_slp_vnqihi_store_usage):
	New function.
	(check_effective_target_vect_slp_v2qi_store): Ditto.
	(check_effective_target_vect_slp_v4qi_store): Ditto.
	(check_effective_target_vect_slp_v8qi_store): Ditto.
	(check_effective_target_vect_slp_v16qi_store): Ditto.
	(check_effective_target_vect_slp_v2hi_store): Ditto.
	(check_effective_target_vect_slp_v4hi_store): Ditto.
	* c-c++-common/Wstringop-overflow-2-novec.c: New test.
	* gcc.dg/Warray-bounds-51-novec.c: New test.
	* gcc.dg/Warray-bounds-48-novec.c: New test.
	* gcc.dg/Warray-parameter-3-novec.c: New test.
	* gcc.dg/Wstringop-overflow-14-novec.c: New test.
	* gcc.dg/Wstringop-overflow-21-novec.c: New test.
	* gcc.dg/Wstringop-overflow-76-novec.c: New test.
---
 .../c-c++-common/Wstringop-overflow-2-novec.c | 348 +++++++++++++++++
 .../c-c++-common/Wstringop-overflow-2.c       |  26 +-
 gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c | 364 ++++++++++++++++++
 gcc/testsuite/gcc.dg/Warray-bounds-48.c       |   6 +-
 gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c |  61 +++
 gcc/testsuite/gcc.dg/Warray-bounds-51.c       |   3 +-
 .../gcc.dg/Warray-parameter-3-novec.c         |  89 +++++
 gcc/testsuite/gcc.dg/Warray-parameter-3.c     |   3 +-
 .../gcc.dg/Wstringop-overflow-14-novec.c      |  56 +++
 gcc/testsuite/gcc.dg/Wstringop-overflow-14.c  |   5 +-
 .../gcc.dg/Wstringop-overflow-21-novec.c      |  59 +++
 gcc/testsuite/gcc.dg/Wstringop-overflow-21.c  |  10 +-
 gcc/testsuite/gcc.dg/Wstringop-overflow-68.c  |  17 +-
 .../gcc.dg/Wstringop-overflow-76-novec.c      | 147 +++++++
 gcc/testsuite/gcc.dg/Wstringop-overflow-76.c  |  26 +-
 gcc/testsuite/lib/target-supports.exp         | 129 +++++++
 16 files changed, 1314 insertions(+), 35 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
 create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
 create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
 create mode 100644 gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
 create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
 create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
 create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c

diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c b/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
new file mode 100644
index 00000000000..89e6a5c12c2
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
@@ -0,0 +1,348 @@
+/* PR middle-end/91458 - inconsistent warning for writing past the end
+   of an array member
+   { dg-do compile }
+   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds -fno-ipa-icf" } */
+
+void sink (void*);
+
+// Exercise flexible array members.
+
+struct Ax
+{
+  char n;
+  char a[];                     // { dg-message "destination object" "note" }
+};
+
+// Verify warning for a definition with no initializer.
+struct Ax ax_;
+
+void gax_ (void)
+{
+  ax_.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  ax_.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  ax_.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+// Verify warning for access to a definition with an initializer that doesn't
+// initialize the flexible array member.
+struct Ax ax0 = { 0 };
+
+void gax0 (void)
+{
+  ax0.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  ax0.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  ax0.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the flexible array member to empty.
+struct Ax ax0_ = { 0, { } };
+
+void gax0_ (void)
+{
+  ax0_.a[0] = 0;                // { dg-warning "\\\[-Wstringop-overflow" }
+  ax0_.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
+  ax0_.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+// Verify warning for out-of-bounds accesses to a definition with
+// an initializer.
+struct Ax ax1 = { 1, { 0 } };
+
+void gax1 (void)
+{
+  ax1.a[0] = 0;
+  ax1.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  ax1.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+struct Ax ax2 = { 2, { 1, 0 } };
+
+void gax2 (void)
+{
+  ax2.a[0] = 0;
+  ax2.a[1] = 1;
+  ax2.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+
+// Verify no warning for an unknown struct object.
+void gaxp (struct Ax *p)
+{
+  p->a[0] = 0;
+  p->a[3] = 3;
+  p->a[9] = 9;
+}
+
+
+// Verify no warning for an extern struct object whose array may be
+// initialized to any number of elements.
+extern struct Ax axx;
+
+void gaxx (void)
+{
+  axx.a[0] = 0;
+  axx.a[3] = 3;
+  axx.a[9] = 9;
+}
+
+// Exercise zero-length array members.
+
+struct A0
+{
+  char n;
+  char a[0];                    // { dg-message "destination object" "note" }
+};
+
+// Verify warning for a definition with no initializer.
+struct A0 a0_;
+
+void ga0_ (void)
+{
+  a0_.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a0_.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a0_.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+// Verify warning for access to a definition with an initializer that doesn't
+// initialize the flexible array member.
+struct A0 a00 = { 0 };
+
+void ga00 (void)
+{
+  a00.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a00.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a00.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the flexible array member to empty.
+struct A0 a00_ = { 0, { } };
+
+void ga00_ (void)
+{
+  a00_.a[0] = 0;                // { dg-warning "\\\[-Wstringop-overflow" }
+  a00_.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
+  a00_.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+// The following are rejected with
+//   error: too many initializers for 'char [0]'
+// A0 a01 = { 1, { 0 } };
+// A0 a02 = { 2, { 1, 0 } };
+
+
+// Verify no warning for an unknown struct object.
+void ga0p (struct A0 *p)
+{
+  p->a[0] = 0;
+  p->a[3] = 3;
+  p->a[9] = 9;
+}
+
+
+// Verify warning for an extern struct object which (unlike a true
+// flexible array member) may not be initialized.
+extern struct A0 a0x;
+
+void ga0x (void)
+{
+  a0x.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a0x.a[3] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a0x.a[9] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+
+// Exercise trailing one-element array members.
+
+struct A1
+{
+  char n;
+  char a[1];                    // { dg-message "destination object" "note" }
+};
+
+// Verify warning for a definition with no initializer.
+struct A1 a1_;
+
+void ga1_ (void)
+{
+  a1_.a[0] = 0;
+  a1_.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a1_.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a;
+  a.a[0] = 0;
+  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that doesn't
+// initialize the one-element array member.
+struct A1 a1__ = { 0 };
+
+void ga1__ (void)
+{
+  a1__.a[0] = 0;
+  a1__.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a1__.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a = { 1 };
+  a.a[0] = 0;
+  a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the one-element array member to empty.
+struct A1 a1_0 = { 0, { } };
+
+void ga1_0_ (void)
+{
+  a1_0.a[0] = 0;
+  a1_0.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
+  a1_0.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a = { 1, { } };
+  a.a[0] = 0;
+  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the one-element array member.
+struct A1 a1_1 = { 0, { 1 } };
+
+void ga1_1 (void)
+{
+  a1_1.a[0] = 0;
+  a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
+  a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a = { 0, { 1 } };
+  a.a[0] = 0;
+  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+
+// Verify no warning for an unknown struct object.
+void ga1p (struct A1 *p)
+{
+  p->a[0] = 0;
+  p->a[3] = 3;
+  p->a[9] = 9;
+}
+
+
+// Verify warning for an extern struct object.  Similar to the zero-length
+// array case, a one-element trailing array can be initialized to at most
+// a single element.
+extern struct A1 a1x;
+
+void ga1x (void)
+{
+  a1x.a[0] = 0;
+  a1x.a[3] = 3;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a1x.a[9] = 9;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+// Exercise interior one-element array members (verify they're not
+// treated as trailing.
+
+struct A1i
+{
+  char n;
+  char a[1];                    // { dg-message "destination object" }
+  char x;
+};
+
+// Verify warning for a definition with no initializer.
+struct A1i a1i_;
+
+void ga1i_ (void)
+{
+  a1i_.a[0] = 0;
+  a1i_.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
+  a1i_.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1i a;
+  a.a[0] = 1;
+  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that doesn't
+// initialize the one-element array member.
+struct A1i a1i__ = { 0 };
+
+void ga1i__ (void)
+{
+  a1i__.a[0] = 0;
+  a1i__.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
+  a1i__.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1i a = { 0 };
+  a.a[0] = 0;
+  a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the one-element array member to empty.
+struct A1 a1i_0 = { 0, { } };
+
+void ga1i_0_ (void)
+{
+  a1i_0.a[0] = 0;
+  a1i_0.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow" }
+  a1i_0.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a = { 0, { } };
+  a.a[0] = 0;
+  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the one-element array member.
+struct A1 a1i_1 = { 0, { 1 } };
+
+void ga1i_1 (void)
+{
+  a1i_1.a[0] = 0;
+  a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow" }
+  a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a = { 0, { 1 } };
+  a.a[0] = 1;
+  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+
+// Verify no warning for an unknown struct object.
+void ga1ip (struct A1i *p)
+{
+  p->a[0] = 0;
+  p->a[3] = 3;                  // { dg-warning "\\\[-Wstringop-overflow" }
+  p->a[9] = 9;                  // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+
+// Verify no warning for an extern struct object.
+extern struct A1i a1ix;
+
+void ga1ix (void)
+{
+  a1ix.a[0] = 0;
+  a1ix.a[3] = 3;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a1ix.a[9] = 9;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
index 7d29b5f48c7..cb687c69324 100644
--- a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
+++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
@@ -189,8 +189,9 @@ void ga1__ (void)
 
   struct A1 a = { 1 };
   a.a[0] = 0;
+  // O2 vectorization regress Wstringop-overflow case (1), refer to pr102462.
   a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
-  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store } } }
   sink (&a);
 }
 
@@ -206,8 +207,9 @@ void ga1_0_ (void)
 
   struct A1 a = { 1, { } };
   a.a[0] = 0;
+  // O2 vectorization regress Wstringop-overflow case (1), refer to PR102462.
   a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
-  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store } } }
   sink (&a);
 }
 
@@ -221,10 +223,11 @@ void ga1_1 (void)
   a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
   a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
 
-  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+// O2 vectorization regress Wstringop-overflow case (2), refer to PR102706
+  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v4qi_store } } }
   a.a[0] = 0;
-  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
-  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store } } }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store } } }
   sink (&a);
 }
 
@@ -288,8 +291,9 @@ void ga1i__ (void)
 
   struct A1i a = { 0 };
   a.a[0] = 0;
+  // O2 vectorization regress Wstringop-overflow case (1), refer to PR102462
   a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
-  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store } } }
   sink (&a);
 }
 
@@ -305,8 +309,9 @@ void ga1i_0_ (void)
 
   struct A1 a = { 0, { } };
   a.a[0] = 0;
+  // O2 vectorization regress Wstringop-overflow case (1), refer to PR102462
   a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
-  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store } } }
   sink (&a);
 }
 
@@ -320,10 +325,11 @@ void ga1i_1 (void)
   a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow" }
   a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow" }
 
-  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  // O2 vectorization regress Wstringop-overflow case (1), refer to PR102462
+  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v4qi_store } } }
   a.a[0] = 1;
-  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
-  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store } } }
+  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store } } }
   sink (&a);
 }
 
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
new file mode 100644
index 00000000000..da179a2c0f5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
@@ -0,0 +1,364 @@
+/* PR middle-end/91647 - missing -Warray-bounds accessing a zero-length array
+   of a declared object
+   { dg-do "compile" }
+   { dg-options "-O2 -Wall -fno-tree-vectorize" }
+   { dg-require-effective-target alloca } */
+
+typedef __INT16_TYPE__ int16_t;
+typedef __INT32_TYPE__ int32_t;
+
+void sink (void*);
+
+/* Exercise a true flexible member.  */
+
+struct AX
+{
+  int32_t n;
+  int16_t ax[];     // { dg-message "while referencing 'ax'" "member" }
+};
+
+static void warn_ax_local (struct AX *p)
+{
+  p->ax[0] = 0;     // { dg-warning "\\\[-Warray-bounds" }
+  p->ax[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void nowarn_ax_extern (struct AX *p)
+{
+  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
+}
+
+static void warn_ax_local_buf (struct AX *p)
+{
+  p->ax[0] = 4; p->ax[1] = 5;
+
+  p->ax[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
+  p->ax[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
+  p->ax[4] = 8;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_ax_extern_buf (struct AX *p)
+{
+  p->ax[0] = 9; p->ax[1] = 10; p->ax[2] = 11;
+
+  p->ax[3] = 12;    // { dg-warning "\\\[-Warray-bounds" }
+  p->ax[4] = 13;    // { dg-warning "\\\[-Warray-bounds" }
+  p->ax[5] = 14;    // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void nowarn_ax_extern_bufx (struct AX *p)
+{
+  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
+}
+
+static void nowarn_ax_ref (struct AX *p)
+{
+  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
+}
+
+void test_ax (struct AX *p, unsigned n)
+{
+  {
+    struct AX sax;  // { dg-message "defined here" "struct definition" }
+    warn_ax_local (&sax);
+    sink (&sax);
+  }
+
+  {
+    extern
+      struct AX xsax;
+    nowarn_ax_extern (&xsax);
+    sink (&xsax);
+  }
+
+  {
+    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
+    char ax_buf_p2[sizeof (struct AX) + 2 * sizeof (int16_t)];
+    warn_ax_local_buf ((struct AX*) ax_buf_p2);
+    sink (ax_buf_p2);
+  }
+
+  {
+    /* Verify out-of-bounds access to the extern BUF with a known
+       bound is diagnosed.  */
+    extern char ax_buf_p3[sizeof (struct AX) + 3 * sizeof (int16_t)];
+    warn_ax_extern_buf ((struct AX*) ax_buf_p3);
+    sink (ax_buf_p3);
+  }
+
+  {
+    /* Verify that accesses to BUFX with an unknown bound are not
+       diagnosed.  */
+    extern char bufx[];
+    nowarn_ax_extern_bufx ((struct AX*) bufx);
+    sink (bufx);
+  }
+
+  {
+    /* Verify that accesses to BUFN with a runtime bound are not
+       diagnosed.  */
+    char bufn[n];
+    nowarn_ax_extern_bufx ((struct AX*) bufn);
+    sink (bufn);
+  }
+
+  nowarn_ax_ref (p);
+}
+
+
+/* Exercise a zero-length trailing member array.  It's the same as above
+   except that extern declarations with no definitions are considered to
+   have zero elements (they can't be initialized to have any).  */
+
+struct A0
+{
+  int32_t n;
+  int16_t a0[0];    // { dg-message "while referencing 'a0'" "member" }
+};
+
+static void warn_a0_local (struct A0 *p)
+{
+  p->a0[0] = 0;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a0[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a0_extern (struct A0 *p)
+{
+  p->a0[0] = 2;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a0[1] = 3;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a0_local_buf (struct A0 *p)
+{
+  p->a0[0] = 4; p->a0[1] = 5;
+
+  p->a0[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a0[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a0[4] = 8;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a0_extern_buf (struct A0 *p)
+{
+  p->a0[0] = 9; p->a0[1] = 10; p->a0[2] = 11;
+
+  p->a0[3] = 12;    // { dg-warning "\\\[-Warray-bounds" }
+  p->a0[4] = 13;    // { dg-warning "\\\[-Warray-bounds" }
+  p->a0[5] = 14;    // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void nowarn_a0_extern_bufx (struct A0 *p)
+{
+  p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
+}
+
+static void nowarn_a0_ref (struct A0 *p)
+{
+  p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
+}
+
+void test_a0 (struct A0 *p, unsigned n)
+{
+  {
+    struct A0 sa0;  // { dg-message "defined here" "struct definition" }
+    warn_a0_local (&sa0);
+    sink (&sa0);
+  }
+
+  {
+    extern
+      struct A0 xsa0;  // { dg-message "defined here" "struct definition" }
+    warn_a0_extern (&xsa0);
+    sink (&xsa0);
+  }
+
+  {
+    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
+    char a0_buf_p2[sizeof (struct A0) + 2 * sizeof (int16_t)];
+    warn_a0_local_buf ((struct A0*) a0_buf_p2);
+    sink (a0_buf_p2);
+  }
+
+  {
+    /* Verify out-of-bounds access to the extern BUF with a known
+       bound is diagnosed.  */
+    extern char a0_buf_p3[sizeof (struct A0) + 3 * sizeof (int16_t)];
+    warn_a0_extern_buf ((struct A0*) a0_buf_p3);
+    sink (a0_buf_p3);
+  }
+
+  {
+    /* Verify that accesses to BUFX with an unknown bound are not
+       diagnosed.  */
+    extern char bufx[];
+    nowarn_a0_extern_bufx ((struct A0*) bufx);
+    sink (bufx);
+  }
+
+  {
+    /* Verify that accesses to BUFN with a runtime bound are not
+       diagnosed.  */
+    char bufn[n];
+    nowarn_a0_extern_bufx ((struct A0*) bufn);
+    sink (bufn);
+  }
+
+  nowarn_a0_ref (p);
+}
+
+
+/* Exercise a one-element trailing member array.  It's the same as above
+   except that it has exactly one element.  */
+
+struct A1
+{
+  int32_t n;
+  int16_t a1[1];    // { dg-message "while referencing 'a1'" }
+};
+
+static void warn_a1_local_noinit (struct A1 *p)
+{
+  p->a1[0] = 0;
+  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a1_extern (struct A1 *p)
+{
+  p->a1[0] = 0;
+  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a1_init (struct A1 *p)
+{
+  p->a1[0] = 0;
+  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a1_local_buf (struct A1 *p)
+{
+  p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3;
+
+  p->a1[4] = 4;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a1_extern_buf (struct A1 *p)
+{
+  p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3; p->a1[4] = 4;
+
+  p->a1[5] = 5;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void nowarn_a1_extern_bufx (struct A1 *p)
+{
+  p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
+}
+
+static void nowarn_a1_ref (struct A1 *p)
+{
+  p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
+}
+
+void test_a1 (struct A1 *p, unsigned n)
+{
+  {
+    struct A1 a1;
+    warn_a1_local_noinit (&a1);
+    sink (&a1);
+  }
+
+  {
+    extern struct A1 a1x;
+    warn_a1_extern (&a1x);
+    sink (&a1x);
+}
+  {
+    struct A1 a1 = { 0, { 1 } };
+    warn_a1_init (&a1);
+    sink (&a1);
+  }
+
+  {
+    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
+    char buf_p2[sizeof (struct A1) + 2 * sizeof (int16_t)];
+    warn_a1_local_buf ((struct A1*) buf_p2);
+    sink (buf_p2);
+  }
+
+  {
+    /* Verify out-of-bounds access to the extern BUF with a known
+       bound is diagnosed.  */
+    extern char a1_buf_p3[sizeof (struct A1) + 3 * sizeof (int16_t)];
+    warn_a1_extern_buf ((struct A1*) a1_buf_p3);
+    sink (a1_buf_p3);
+  }
+
+  {
+    /* Verify that accesses to BUFX with an unknown bound are not
+       diagnosed.  */
+    extern char bufx[];
+    nowarn_a1_extern_bufx ((struct A1*) bufx);
+    sink (bufx);
+  }
+
+  {
+    /* Verify that accesses to BUFN with a runtime bound are not
+       diagnosed.  */
+    char bufn[n];
+    nowarn_a1_extern_bufx ((struct A1*) bufn);
+    sink (bufn);
+  }
+
+  nowarn_a1_ref (p);
+}
+
+
+/* Exercise a two-element trailing member array.  It's treated
+   the same as an interior array member.  */
+
+struct A2
+{
+  int32_t n;
+  int16_t a2[2];    // { dg-message "while referencing 'a2'" }
+};
+
+static void warn_a2_noinit (struct A2 *p)
+{
+  p->a2[0] = 0; p->a2[1] = 1;
+
+  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a2_init (struct A2 *p)
+{
+  p->a2[0] = 0; p->a2[1] = 1;
+
+  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a2[9] = 9;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a2_ref (struct A2 *p)
+{
+  p->a2[0] = 0; p->a2[1] = 1;
+
+  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a2[9] = 9;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+void test_a2 (struct A2 *p)
+{
+  {
+    struct A2 a2;
+    warn_a2_noinit (&a2);
+    sink (&a2);
+  }
+
+  {
+    struct A2 a2 = { 0, { 1, 2 } };
+    warn_a2_init (&a2);
+    sink (&a2);
+  }
+
+  warn_a2_ref (p);
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48.c b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
index 13373d1e99e..27dd879de5c 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-48.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
@@ -30,7 +30,8 @@ static void nowarn_ax_extern (struct AX *p)
 
 static void warn_ax_local_buf (struct AX *p)
 {
-  p->ax[0] = 4; p->ax[1] = 5;
+  // Refer to 102706
+  p->ax[0] = 4; p->ax[1] = 5;  // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v2hi_store &&  { ! vect_slp_v4hi_store } } } }
 
   p->ax[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
   p->ax[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
@@ -130,7 +131,8 @@ static void warn_a0_extern (struct A0 *p)
 
 static void warn_a0_local_buf (struct A0 *p)
 {
-  p->a0[0] = 4; p->a0[1] = 5;
+  // Refer to 102706
+  p->a0[0] = 4; p->a0[1] = 5;  // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v2hi_store && { ! vect_slp_v4hi_store } } } }
 
   p->a0[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
   p->a0[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c b/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
new file mode 100644
index 00000000000..24bc318f113
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
@@ -0,0 +1,61 @@
+/* PR middle-end/92333 - missing variable name referencing VLA in warnings
+   PR middle-end/82608 - missing -Warray-bounds on an out-of-bounds VLA index
+   { dg-do compile }
+   { dg-options "-O2 -Wall -fno-tree-vectorize" }  */
+
+void sink (void*);
+
+void test_char_vla_location (void)
+{
+  unsigned nelts = 7;
+
+  char vla[nelts];    // { dg-message "declared here|while referencing" }
+
+  vla[0] = __LINE__;
+  vla[nelts] = 0;     // { dg-warning "\\\[-Warray-bounds" }
+
+  sink (vla);
+}
+
+void test_int_vla_location (void)
+{
+  unsigned nelts = 7;
+
+  int vla[nelts];     // { dg-message "declared here|while referencing" }
+
+  vla[0] = __LINE__;
+  vla[nelts] = 1;     // { dg-warning "\\\[-Warray-bounds" }
+
+  sink (vla);
+}
+
+void test_struct_char_vla_location (void)
+{
+  unsigned nelts = 7;
+
+  struct {
+    char cvla[nelts]; // { dg-message "declared here|while referencing" }
+  } s;
+
+  s.cvla[0] = __LINE__;
+  s.cvla[nelts - 1] = 0;
+  s.cvla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
+
+  sink (&s);
+}
+
+
+void test_struct_int_vla_location (void)
+{
+  unsigned nelts = 7;
+
+  struct {
+    int ivla[nelts];  // { dg-message "declared here|while referencing" }
+  } s;
+
+  s.ivla[0] = __LINE__;
+  s.ivla[nelts - 1] = 0;
+  s.ivla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
+
+  sink (&s);
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-51.c b/gcc/testsuite/gcc.dg/Warray-bounds-51.c
index de60d87ab95..cc92a0fd500 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-51.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-51.c
@@ -39,7 +39,8 @@ void test_struct_char_vla_location (void)
   } s;
 
   s.cvla[0] = __LINE__;
-  s.cvla[nelts - 1] = 0; // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  // O2 vectorization regress Wstringop-overflow case (2), refer to pr102706.
+  s.cvla[nelts - 1] = 0; // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v2qi_store } } }
   s.cvla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
 
   sink (&s);
diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c b/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
new file mode 100644
index 00000000000..0c8fdd11ec9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
@@ -0,0 +1,89 @@
+/* PR c/50584 - No warning for passing small array to C99 static array
+   declarator
+   { dg-do compile }
+   { dg-options "-Wall -Warray-parameter=1" } */
+
+/* Verify that at level 1 mismatches in the bounds of ordinary array
+   parameters don't trigger -Warray-parameter.  */
+void fax (int[]);
+void fax (int[0]);
+void fax (int[1]);
+void fax (int[2]);
+void fax (int[3]);
+
+/* Same as above but starting with an array with a specified bound.  */
+void gax (int[3]);
+void gax (int[2]);
+void gax (int[1]);
+void gax (int[0]);
+void gax (int[]);
+
+/* Same for multidimensional arrays.  */
+void fax_y (int[][3]);
+void fax_y (int[0][3]);
+void fax_y (int[1][3]);
+void fax_y (int[2][3]);
+void fax_y (int[3][3]);
+
+/* Same as above but starting with an array with a specified bound.  */
+void gax_y (int[3][5]);
+void gax_y (int[2][5]);
+void gax_y (int[1][5]);
+void gax_y (int[0][5]);
+void gax_y (int[][5]);
+
+/* Exercise VLAs with a mismatch in the bound for an ordinary array.  */
+void fvlax_y (int n, int[][n]);
+void fvlax_y (int n, int[0][n]);
+void fvlax_y (int n, int[1][n]);
+void fvlax_y (int n, int[2][n]);
+void fvlax_y (int n, int[3][n]);
+
+void fvlaxn_y (int n, int[][n]);
+void fvlaxn_y (int n, int[0][n]);
+void fvlaxn_y (int n, int[1][n]);
+void fvlaxn_y (int n, int[2][n]);
+void fvlaxn_y (int n, int[3][n]);
+
+void fvlaxx_y (int[][*]);
+void fvlaxx_y (int[0][*]);
+void fvlaxx_y (int[1][*]);
+void fvlaxx_y (int[2][*]);
+void fvlaxx_y (int[3][*]);
+
+/* Verify that mismatches in the bounds of array parameters declared
+   static do trigger -Warray-parameter.  */
+void fas1 (int[static 1]);    // { dg-message "previously declared as 'int\\\[static 1]'" }
+void fas1 (int[static 2]);    // { dg-warning "\\\[-Warray-parameter=" }
+
+
+/* Also verify that -Warray-bounds doesn't trigger for ordinary array
+   parameters...  */
+#pragma GCC optimize ("2,no-tree-vectorize")
+
+__attribute__ ((noipa)) void
+gca3 (char a[3])
+{
+  a[0] = 0; a[1] = 1; a[2] = 2; a[3] = 3;
+}
+
+__attribute__ ((noipa)) void
+gia3 (int a[3])
+{
+  a[0] = 0; a[1] = 1; a[2] = 2; a[3] = 3;
+}
+
+/* ...but does for static arrays.  */
+__attribute__ ((noipa)) void
+gcas3 (char a[static 3])
+{
+  a[0] = 0; a[1] = 1; a[2] = 2;
+  a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
+}
+
+__attribute__ ((noipa)) void
+gias3 (int a[static 3])
+{
+  a[0] = 0; a[1] = 1; a[2] = 2;
+  a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3.c b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
index e8a269c85c6..1068707973f 100644
--- a/gcc/testsuite/gcc.dg/Warray-parameter-3.c
+++ b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
@@ -77,7 +77,8 @@ gia3 (int a[3])
 __attribute__ ((noipa)) void
 gcas3 (char a[static 3])
 {
-  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  // O2 vectorization regress Wstringop-overflow case (2), refer to pr102706.
+  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v4qi_store } } }
   a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
 }
 
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
new file mode 100644
index 00000000000..c7b5479dc07
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
@@ -0,0 +1,56 @@
+/* Test to verify that past-the-end multibyte writes via lvalues of wider
+   types than char are diagnosed.
+   { dg-do compile }
+   { dg-require-effective-target int32plus }
+   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds" }  */
+
+typedef __INT16_TYPE__  int16_t;
+typedef __INT32_TYPE__  int32_t;
+typedef __INT64_TYPE__  int64_t;
+typedef __SIZE_TYPE__   size_t;
+
+void* memcpy (void*, const void*, size_t);
+char* strcpy (char*, const char*);
+
+char a4[4], a8[8], a16[16];
+
+const char s4[] = "1234";
+const char t4[] = "4321";
+
+void test_memcpy_cond (int i)
+{
+  char *p = a4 + 1;
+  const char *q = i ? s4 : t4;
+  // On strictly aligned target the call below is left unchanged and
+  // triggers (inaccurately) a -Warray-bounds.  The test suppresses
+  // the warning above, which then lets -Wstringop-overrflow detect
+  // the overflow just before expansion.
+  // On other targets it's transformed into a store of a 4-byte integer
+  // which is detected by -Wstringop-overrflow in the strlen pass (i.e.,
+  // before it gets to expansion).
+  memcpy (p, q, 4);         // { dg-warning "writing 4 bytes into a region of size 3" }
+}
+
+
+void test_int16 (void)
+{
+  char *p = a4 + 1;
+  *(int16_t*)p = 0;
+  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a region of size 1" }
+}
+
+
+void test_int32 (void)
+{
+  char *p = a8 + 3;
+  *(int32_t*)p = 0;
+  *(int32_t*)(p + 2) = 0;   // { dg-warning "writing 4 bytes into a region of size 3" }
+}
+
+
+void test_int64 (void)
+{
+  char *p = a16 + 5;
+  *(int64_t*)p = 0;
+  *(int64_t*)(p + 5) = 0;   // { dg-warning "writing 8 bytes into a region of size 6" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
index 7683084e46e..6ad9444bc27 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
@@ -36,8 +36,9 @@ void test_memcpy_cond (int i)
 void test_int16 (void)
 {
   char *p = a4 + 1;
-  *(int16_t*)p = 0;    // { dg-warning "writing 4 bytes into a region of size 3" "" { target { i?86-*-* x86_64-*-* } } }
-  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a region of size 1" "" { xfail { i?86-*-* x86_64-*-* } } }
+  // O2 vectorization regress Wstringop-overflow case (2), refer to pr102706.
+  *(int16_t*)p = 0;    // { dg-warning "writing 4 bytes into a region of size 3" "" { target { vect_slp_v2hi_store } } }
+  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a region of size 1" "" { xfail { vect_slp_v2hi_store } } }
 }
 
 
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
new file mode 100644
index 00000000000..b177543b186
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
@@ -0,0 +1,59 @@
+/* PR middle-end/92312 - bogus -Wstringop-overflow storing into a trailing
+   array backed by larger buffer
+   { dg-do compile }
+   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds" } */
+
+struct S0 { char a, b[0]; };
+
+void sink (void*);
+
+void test_memset_zero_length (void)
+{
+  char a[3];
+  struct S0 *p = (struct S0*)a;
+  p->a = 0;
+  __builtin_memset (p->b, 0, 2);
+  sink (p);
+
+  __builtin_memset (p->b, 0, 3);    // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (p);
+}
+
+void test_store_zero_length (int i)
+{
+  char a[3];
+  struct S0 *p = (struct S0*)a;
+  p->a = 0;
+  p->b[0] = 0;
+  p->b[1] = 1;                      // { dg-bogus "\\\[-Wstringop-overflow" }
+  p->b[2] = 2;                      // { dg-warning "\\\[-Wstringop-overflow" }
+  p->b[i] = 2;
+  sink (p);
+}
+
+
+struct Sx { char a, b[]; };
+
+void test_memset_flexarray (int i)
+{
+  char a[3];
+  struct Sx *p = (struct Sx*)a;
+  p->a = 0;
+  __builtin_memset (p->b, 0, 2);
+  sink (p);
+
+  __builtin_memset (p->b, 0, 3);    // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (p);
+}
+
+void test_store_flexarray (int i)
+{
+  char a[3];
+  struct Sx *p = (struct Sx*)a;
+  p->a = 0;
+  p->b[0] = 0;
+  p->b[1] = 1;                      // { dg-bogus "\\\[-Wstringop-overflow" }
+  p->b[2] = 1;                      // { dg-warning "\\\[-Wstringop-overflow" }
+  p->b[i] = 2;
+  sink (p);
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
index d88bde9c740..8d2bfe697a5 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
@@ -23,10 +23,11 @@ void test_store_zero_length (int i)
 {
   char a[3];
   struct S0 *p = (struct S0*)a;
-  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  // O2 vectorization regress Wstringop-overflow case (2), refer to pr102706.
+  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v4qi_store } } }
   p->b[0] = 0;
   p->b[1] = 1;                      // { dg-bogus "\\\[-Wstringop-overflow" }
-  p->b[2] = 2;                      // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  p->b[2] = 2;                      // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store } } }
   p->b[i] = 2;
   sink (p);
 }
@@ -50,10 +51,11 @@ void test_store_flexarray (int i)
 {
   char a[3];
   struct Sx *p = (struct Sx*)a;
-  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  // O2 vectorization regress Wstringop-overflow case (2), refer to pr102706.
+  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v4qi_store } } }
   p->b[0] = 0;
   p->b[1] = 1;                      // { dg-bogus "\\\[-Wstringop-overflow" }
-  p->b[2] = 1;                      // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  p->b[2] = 1;                      // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store } } }
   p->b[i] = 2;
   sink (p);
 }
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
index 09df0004991..04e91afb8bc 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
@@ -58,11 +58,18 @@ void warn_comp_lit_zero (void)
 void warn_comp_lit (void)
 {
   *(AC2*)a1 = Ac2;      // { dg-warning "writing 2 bytes into a region of size 1" "pr101475" { xfail *-*-* } }
-  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 2" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
-  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 3" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
-  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 4" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
-  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 7" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
-  *(AC16*)a15 = Ac16;   // { dg-warning "writing 16 bytes into a region of size 15" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
+  // After vectorization, below codes are optimized to
+  // MEM <vector(4) char> [(char *)&a2] = { 0, 1, 2, 3 };
+  // MEM <vector(4) char> [(char *)&a3] = { 0, 1, 2, 3 };
+  // MEM <vector(8) char> [(char *)&a4] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+  // MEM <vector(8) char> [(char *)&a7] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+  // MEM <vector(16) char> [(char *)&a15] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+  // and warning should be expected, refer to PR102722.
+  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 2" "pr101475" { xfail { ! { vect_slp_v4qi_store } } } }
+  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 3" "pr101475" { xfail { ! { vect_slp_v4qi_store } } } }
+  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 4" "pr101475" { xfail { ! { vect_slp_v8qi_store } } } }
+  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 7" "pr101475" { xfail { ! { vect_slp_v8qi_store } } } }
+  *(AC16*)a15 = Ac16;   // { dg-warning "writing 16 bytes into a region of size 15" "pr101475" { xfail { ! { vect_slp_v16qi_store } } } }
 }
 
 void warn_aggr_decl (void)
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
new file mode 100644
index 00000000000..d000b587a65
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
@@ -0,0 +1,147 @@
+/* Verify warnings and notes for MAX_EXPRs involving either pointers
+   to distinct objects or one to a known object and the other to
+   an unknown one.  Unlike for the same object, for unrelated objects
+   the expected warnings and notes are the same as for MIN_EXPR: when
+   the order of the objects in the address space cannot be determined
+   the larger of them is assumed to be used.  (This is different for
+   distinct struct members where the order is given.)
+   The relational expressions are strictly invalid but that should be
+   diagnosed by a separate warning.
+   { dg-do compile }
+   { dg-options "-O2 -Wno-array-bounds -fno-tree-vectorize" } */
+
+#define MAX(p, q) ((p) > (q) ? (p) : (q))
+
+/* Verify that even for MAX_EXPR and like for MIN_EXPR, the note points
+   to the larger of the two objects and mentions the offset into it
+   (although the offset might be better included in the warning).  */
+extern char a3[3];
+extern char a5[5];  // { dg-message "at offset 5 into destination object 'a5' of size 5" "note" }
+
+void max_a3_a5 (int i)
+{
+  char *p = a3 + i;
+  char *q = a5 + i;
+
+  /* The relational expression below is invalid and should be diagnosed
+     by its own warning independently of -Wstringop-overflow.  */
+  char *d = MAX (p, q);
+
+  d[2] = 0;
+  d[3] = 0;
+  d[4] = 0;
+  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
+}
+
+
+// Same as above but with the larger array as the first MAX_EXPR operand.
+extern char b4[4];
+extern char b6[6];  // { dg-message "at offset 6 into destination object 'b6' of size 6" "note" }
+
+void max_b6_b4 (int i)
+{
+  char *p = b6 + i;
+  char *q = b4 + i;
+  char *d = MAX (p, q);
+
+  d[3] = 0;
+  d[4] = 0;
+  d[5] = 0;
+  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
+}
+
+
+/* Same as above but with the first MAX_EXPR operand pointing to an unknown
+   object.  */
+extern char c7[7];  // { dg-message "at offset 7 into destination object 'c7' of size 7" "note" }
+
+void max_p_c7 (char *p, int i)
+{
+  char *q = c7 + i;
+  char *d = MAX (p, q);
+
+  d[6] = 0;
+  d[7] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
+}
+
+
+/* Same as above but with the second MIN_EXPR operand pointing to an unknown
+   object.  */
+extern char d8[8];  // { dg-message "at offset 8 into destination object 'd8' of size 8" "note" }
+
+void max_d8_p (char *q, int i)
+{
+  char *p = d8 + i;
+  char *d = MAX (p, q);
+
+  d[7] = 0;
+  d[8] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
+}
+
+
+struct A3_5
+{
+  char a3[3];  // { dg-message "at offset 3 into destination object 'a3' of size 3" "pr??????" { xfail *-*-* } }
+  char a5[5];
+};
+
+void max_A3_A5 (int i, struct A3_5 *pa3_5)
+{
+  char *p = pa3_5->a3 + i;
+  char *q = pa3_5->a5 + i;
+
+  char *d = MAX (p, q);
+  d[2] = 0;
+  d[3] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "pr??????" { xfail *-*-* } }
+  d[4] = 0;
+  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
+}
+
+
+struct B4_B6
+{
+  char b4[4];
+  char b6[6];       // { dg-message "at offset 6 into destination object 'b6' of size 6" "note" }
+};
+
+void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
+{
+  char *p = pb4_b6->b6 + i;
+  char *q = pb4_b6->b4 + i;
+  char *d = MAX (p, q);
+
+  d[3] = 0;
+  d[4] = 0;
+  d[5] = 0;
+  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
+}
+
+
+struct C7
+{
+  char c7[7];       // { dg-message "at offset 7 into destination object 'c7' of size 7" "note" }
+};
+
+void max_p_C7 (char *p, int i, struct C7 *pc7)
+{
+  char *q = pc7->c7 + i;
+  char *d = MAX (p, q);
+
+  d[6] = 0;
+  d[7] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
+}
+
+
+struct D8
+{
+  char d8[8];       // { dg-message "at offset 8 into destination object 'd8' of size 8" "note" }
+};
+
+void max_D8_p (char *q, int i, struct D8 *pd8)
+{
+  char *p = pd8->d8 + i;
+  char *d = MAX (p, q);
+
+  d[7] = 0;
+  d[8] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
index 0c7b53ccc0b..037e66c2769 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
@@ -27,10 +27,11 @@ void max_a3_a5 (int i)
      by its own warning independently of -Wstringop-overflow.  */
   char *d = MAX (p, q);
 
-  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "" { target { i?86-*-* x86_64-*-* } } }
+  // O2 vectorization regress Wstringop-overflow case (2), refer to pr102706.
+  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "" { target { vect_slp_v4qi_store } } }
   d[3] = 0;
   d[4] = 0;
-  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
+  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { vect_slp_v4qi_store } } }
 }
 
 
@@ -44,10 +45,11 @@ void max_b6_b4 (int i)
   char *q = b4 + i;
   char *d = MAX (p, q);
 
-  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "" { target { i?86-*-* x86_64-*-* } } }
+  // O2 vectorization regress Wstringop-overflow case (2), refer to pr102706.
+  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "" { target { vect_slp_v4qi_store } } }
   d[4] = 0;
   d[5] = 0;
-  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
+  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { vect_slp_v4qi_store } } }
 }
 
 
@@ -82,7 +84,7 @@ void max_d8_p (char *q, int i)
 struct A3_5
 {
   char a3[3];  // { dg-message "at offset 3 into destination object 'a3' of size 3" "pr??????" { xfail *-*-* } }
-  char a5[5];  // { dg-message "at offset 5 into destination object 'a5' of size 5" "note" { xfail { i?86-*-* x86_64-*-* } } }
+  char a5[5];  // { dg-message "at offset 5 into destination object 'a5' of size 5" "note" { xfail { vect_slp_v4qi_store } } }
 };
 
 void max_A3_A5 (int i, struct A3_5 *pa3_5)
@@ -91,18 +93,20 @@ void max_A3_A5 (int i, struct A3_5 *pa3_5)
   char *q = pa3_5->a5 + i;
 
   char *d = MAX (p, q);
-
+  // After vectorization, below codes are vectorized to
+  // MEM <vector(4) char> [(char *)&d + 3] = { 0, 0, 0, 0 };
+  // refer to pr102697.
   d[2] = 0;
   d[3] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "pr??????" { xfail *-*-* } }
   d[4] = 0;
-  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
+  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { vect_slp_v4qi_store } } }
 }
 
 
 struct B4_B6
 {
   char b4[4];
-  char b6[6];       // { dg-message "at offset \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6" "note" { xfail { i?86-*-* x86_64-*-* } } }
+  char b6[6];       // { dg-message "at offset \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6" "note" { xfail { vect_slp_v4qi_store } } }
 };
 
 void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
@@ -110,11 +114,13 @@ void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
   char *p = pb4_b6->b6 + i;
   char *q = pb4_b6->b4 + i;
   char *d = MAX (p, q);
-
+  // After vectorization, below codes are vectorized to
+  // MEM <vector(4) char> [(char *)&d + 3] = { 0, 0, 0, 0 };
+  // refer to pr102697.
   d[3] = 0;
   d[4] = 0;
   d[5] = 0;
-  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
+  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { vect_slp_v4qi_store } } }
 }
 
 
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 9ebca7ac007..c30831ea91d 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -7580,6 +7580,135 @@ proc check_effective_target_vect_element_align_preferred { } {
 		   && [check_effective_target_vect_variable_length] }]
 }
 
+# Return true if vectorization of v2qi/v4qi/v8qi/v16qi/v2hi store is enabed.
+# Return zero if the desirable pattern isn't found.
+# It's used by Warray-bounds/Wstringop-overflow testcases which are
+# regressed by O2 vectorization, refer to PR102697/PR102462/PR102706
+proc check_vect_slp_vnqihi_store_usage { pattern } {
+    global tool
+
+    return [check_cached_effective_target slp_vnqihi_store_usage {
+      set result [check_compile slp_vnqihi_store_usage assembly {
+	  char a[16] __attribute__ ((aligned (16)));
+	  void
+	  foo ()
+	  {
+	      a[0] = 0;
+	      a[1] = 1;
+	      a[2] = 2;
+	      a[3] = 3;
+	      a[4] = 4;
+	      a[5] = 5;
+	      a[6] = 6;
+	      a[7] = 7;
+	  }
+
+	  void
+	  foo1 ()
+	  {
+	      a[0] = 0;
+	      a[1] = 1;
+	      a[2] = 2;
+	      a[3] = 3;
+	      a[4] = 4;
+	      a[5] = 5;
+	      a[6] = 6;
+	      a[7] = 7;
+	      a[8] = 8;
+	      a[9] = 9;
+	      a[10] = 10;
+	      a[11] = 11;
+	      a[12] = 12;
+	      a[13] = 13;
+	      a[14] = 14;
+	      a[15] = 15;
+	  }
+
+	  void
+	  foo2 ()
+	  {
+	      a[0] = 0;
+	      a[1] = 1;
+	      a[2] = 2;
+	      a[3] = 3;
+	  }
+
+	  void
+	  foo3 ()
+	  {
+	      a[0] = 0;
+	      a[1] = 1;
+	  }
+
+	  short b[4] __attribute__((aligned(8)));
+	  void
+	  foo4 ()
+	  {
+	      b[0] = 0;
+	      b[1] = 1;
+	  }
+
+	  void
+	  foo5 ()
+	  {
+	      b[0] = 0;
+	      b[1] = 1;
+	      b[2] = 2;
+	      b[3] = 3;
+	  }
+
+      } "-O2 -fopt-info-all" ]
+
+      # Get compiler emitted messages and delete generated file.
+      set lines [lindex $result 0]
+      set output [lindex $result 1]
+      remote_file build delete $output
+
+      # Capture the vectorized info of v2qi, set it to zero if not found.
+	if { ![regexp $pattern $lines whole val] } then {
+	  set val 0
+      }
+
+      return $val
+    }]
+}
+
+# Return the true if target support vectorization of v2qi store.
+proc check_effective_target_vect_slp_v2qi_store { } {
+    set pattern {add new stmt: MEM <vector\(2\) char>}
+    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
+}
+
+# Return the true if target support vectorization of v4qi store.
+proc check_effective_target_vect_slp_v4qi_store { } {
+    set pattern {add new stmt: MEM <vector\(4\) char>}
+    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
+}
+
+# Return the true if target support vectorization of v2qi store.
+proc check_effective_target_vect_slp_v8qi_store { } {
+    set pattern {add new stmt: MEM <vector\(8\) char>}
+    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
+}
+
+# Return the true if target support vectorization of v4qi store.
+proc check_effective_target_vect_slp_v16qi_store { } {
+    set pattern {add new stmt: MEM <vector\(16\) char>}
+    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
+}
+
+# Return the true if target support vectorization of v2hi store.
+proc check_effective_target_vect_slp_v2hi_store { } {
+    set pattern {add new stmt: MEM <vector\(2\) short int>}
+    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
+}
+
+# Return the true if target support vectorization of v2hi store.
+proc check_effective_target_vect_slp_v4hi_store { } {
+    set pattern {add new stmt: MEM <vector\(4\) short int>}
+    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
+}
+
 # Return 1 if we can align stack data to the preferred vector alignment.
 
 proc check_effective_target_vect_align_stack_vars { } {
-- 
2.18.1


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] Adjust testcase for O2 vectorization.
  2021-10-14  7:11                   ` [PATCH] Adjust testcase for O2 vectorization liuhongt
@ 2021-10-14  7:52                     ` Bernhard Reutner-Fischer
  2021-10-14 10:56                     ` Kewen.Lin
  2021-10-15 15:37                     ` Martin Sebor
  2 siblings, 0 replies; 29+ messages in thread
From: Bernhard Reutner-Fischer @ 2021-10-14  7:52 UTC (permalink / raw)
  To: liuhongt via Gcc-patches; +Cc: rep.dot.nop, liuhongt

On Thu, 14 Oct 2021 15:11:41 +0800
liuhongt via Gcc-patches <gcc-patches@gcc.gnu.org> wrote:

> 	* lib/target-supports.exp (check_vect_slp_vnqihi_store_usage):
> 	New function.
> 	(check_effective_target_vect_slp_v2qi_store): Ditto.
> 	(check_effective_target_vect_slp_v4qi_store): Ditto.
> 	(check_effective_target_vect_slp_v8qi_store): Ditto.
> 	(check_effective_target_vect_slp_v16qi_store): Ditto.
> 	(check_effective_target_vect_slp_v2hi_store): Ditto.
> 	(check_effective_target_vect_slp_v4hi_store): Ditto.

ISTM the doc bits are missing from doc/sourcebuild.texi
(Effective-Target Keywords).

thanks,

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] Adjust testcase for O2 vectorization.
  2021-10-14  7:11                   ` [PATCH] Adjust testcase for O2 vectorization liuhongt
  2021-10-14  7:52                     ` Bernhard Reutner-Fischer
@ 2021-10-14 10:56                     ` Kewen.Lin
  2021-10-15  7:11                       ` Kewen.Lin
  2021-10-15 15:37                     ` Martin Sebor
  2 siblings, 1 reply; 29+ messages in thread
From: Kewen.Lin @ 2021-10-14 10:56 UTC (permalink / raw)
  To: liuhongt; +Cc: crazylht, msebor, gcc-patches

Hi Hongtao,

on 2021/10/14 下午3:11, liuhongt wrote:
> Hi Kewen:
>   Cound you help to verify if this patch fix those regressions
> for rs6000 port.
> 

The ppc64le run just finished, there are still some regresssions:

NA->XPASS: c-c++-common/Wstringop-overflow-2.c  -Wc++-compat   (test for warnings, line 194)
NA->XPASS: c-c++-common/Wstringop-overflow-2.c  -Wc++-compat   (test for warnings, line 212)
NA->XPASS: c-c++-common/Wstringop-overflow-2.c  -Wc++-compat   (test for warnings, line 296)
NA->XPASS: c-c++-common/Wstringop-overflow-2.c  -Wc++-compat   (test for warnings, line 314)
NA->FAIL: gcc.dg/Wstringop-overflow-21-novec.c (test for excess errors)
NA->FAIL: gcc.dg/Wstringop-overflow-21-novec.c  (test for warnings, line 18)
NA->FAIL: gcc.dg/Wstringop-overflow-21-novec.c  (test for warnings, line 29)
NA->FAIL: gcc.dg/Wstringop-overflow-21-novec.c  (test for warnings, line 45)
NA->FAIL: gcc.dg/Wstringop-overflow-21-novec.c  (test for warnings, line 55)
NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 104)
NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 137)
NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 19)
NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 39)
NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 56)
NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 70)
NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c (test for excess errors)
NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 116)
NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 131)
NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 146)
NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 33)
NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 50)
NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 64)
NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 78)
NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 97)
PASS->FAIL: c-c++-common/Wstringop-overflow-2.c  -std=gnu++14 (test for excess errors)
NA->FAIL: c-c++-common/Wstringop-overflow-2.c  -std=gnu++14  (test for warnings, line 229)
NA->FAIL: c-c++-common/Wstringop-overflow-2.c  -std=gnu++14  (test for warnings, line 230)
NA->FAIL: c-c++-common/Wstringop-overflow-2.c  -std=gnu++14  (test for warnings, line 331)
NA->FAIL: c-c++-common/Wstringop-overflow-2.c  -std=gnu++14  (test for warnings, line 332)
// omitting -std=gnu++17, -std=gnu++2a, -std=gnu++98

I'll have a look and get back to you tomorrow.

BR,
Kewen

> As discussed in [1], this patch add xfail/target selector to those
> testcases, also make a copy of them so that they can be tested w/o
> vectorization.
> 
> Newly added xfail/target selectors are used to check the vectorization
> capability of continuous byte/double bytes storage, these scenarios
> are exactly the part of the testcases that regressed after O2
> vectorization.
> 
> [1] https://gcc.gnu.org/pipermail/gcc-patches/2021-October/581456.html.
> 
> gcc/testsuite/ChangeLog
> 
> 	PR middle-end/102722
> 	PR middle-end/102697
> 	PR middle-end/102462
> 	PR middle-end/102706
> 	* c-c++-common/Wstringop-overflow-2.c: Adjust testcase with new
> 	xfail/target selector.
> 	* gcc.dg/Warray-bounds-51.c: Ditto.
> 	* gcc.dg/Warray-parameter-3.c: Ditto.
> 	* gcc.dg/Wstringop-overflow-14.c: Ditto.
> 	* gcc.dg/Wstringop-overflow-21.c: Ditto.
> 	* gcc.dg/Wstringop-overflow-68.c: Ditto.
> 	* gcc.dg/Wstringop-overflow-76.c: Ditto.
> 	* gcc.dg/Warray-bounds-48.c: Ditto.
> 	* lib/target-supports.exp (check_vect_slp_vnqihi_store_usage):
> 	New function.
> 	(check_effective_target_vect_slp_v2qi_store): Ditto.
> 	(check_effective_target_vect_slp_v4qi_store): Ditto.
> 	(check_effective_target_vect_slp_v8qi_store): Ditto.
> 	(check_effective_target_vect_slp_v16qi_store): Ditto.
> 	(check_effective_target_vect_slp_v2hi_store): Ditto.
> 	(check_effective_target_vect_slp_v4hi_store): Ditto.
> 	* c-c++-common/Wstringop-overflow-2-novec.c: New test.
> 	* gcc.dg/Warray-bounds-51-novec.c: New test.
> 	* gcc.dg/Warray-bounds-48-novec.c: New test.
> 	* gcc.dg/Warray-parameter-3-novec.c: New test.
> 	* gcc.dg/Wstringop-overflow-14-novec.c: New test.
> 	* gcc.dg/Wstringop-overflow-21-novec.c: New test.
> 	* gcc.dg/Wstringop-overflow-76-novec.c: New test.
> ---
>  .../c-c++-common/Wstringop-overflow-2-novec.c | 348 +++++++++++++++++
>  .../c-c++-common/Wstringop-overflow-2.c       |  26 +-
>  gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c | 364 ++++++++++++++++++
>  gcc/testsuite/gcc.dg/Warray-bounds-48.c       |   6 +-
>  gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c |  61 +++
>  gcc/testsuite/gcc.dg/Warray-bounds-51.c       |   3 +-
>  .../gcc.dg/Warray-parameter-3-novec.c         |  89 +++++
>  gcc/testsuite/gcc.dg/Warray-parameter-3.c     |   3 +-
>  .../gcc.dg/Wstringop-overflow-14-novec.c      |  56 +++
>  gcc/testsuite/gcc.dg/Wstringop-overflow-14.c  |   5 +-
>  .../gcc.dg/Wstringop-overflow-21-novec.c      |  59 +++
>  gcc/testsuite/gcc.dg/Wstringop-overflow-21.c  |  10 +-
>  gcc/testsuite/gcc.dg/Wstringop-overflow-68.c  |  17 +-
>  .../gcc.dg/Wstringop-overflow-76-novec.c      | 147 +++++++
>  gcc/testsuite/gcc.dg/Wstringop-overflow-76.c  |  26 +-
>  gcc/testsuite/lib/target-supports.exp         | 129 +++++++
>  16 files changed, 1314 insertions(+), 35 deletions(-)
>  create mode 100644 gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
>  create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
>  create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
>  create mode 100644 gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
>  create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
>  create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
>  create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> 
> diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c b/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> new file mode 100644
> index 00000000000..89e6a5c12c2
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> @@ -0,0 +1,348 @@
> +/* PR middle-end/91458 - inconsistent warning for writing past the end
> +   of an array member
> +   { dg-do compile }
> +   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds -fno-ipa-icf" } */
> +
> +void sink (void*);
> +
> +// Exercise flexible array members.
> +
> +struct Ax
> +{
> +  char n;
> +  char a[];                     // { dg-message "destination object" "note" }
> +};
> +
> +// Verify warning for a definition with no initializer.
> +struct Ax ax_;
> +
> +void gax_ (void)
> +{
> +  ax_.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +  ax_.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +  ax_.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +}
> +
> +// Verify warning for access to a definition with an initializer that doesn't
> +// initialize the flexible array member.
> +struct Ax ax0 = { 0 };
> +
> +void gax0 (void)
> +{
> +  ax0.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +  ax0.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +  ax0.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +}
> +
> +// Verify warning for access to a definition with an initializer that
> +// initializes the flexible array member to empty.
> +struct Ax ax0_ = { 0, { } };
> +
> +void gax0_ (void)
> +{
> +  ax0_.a[0] = 0;                // { dg-warning "\\\[-Wstringop-overflow" }
> +  ax0_.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
> +  ax0_.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
> +}
> +
> +// Verify warning for out-of-bounds accesses to a definition with
> +// an initializer.
> +struct Ax ax1 = { 1, { 0 } };
> +
> +void gax1 (void)
> +{
> +  ax1.a[0] = 0;
> +  ax1.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +  ax1.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +}
> +
> +struct Ax ax2 = { 2, { 1, 0 } };
> +
> +void gax2 (void)
> +{
> +  ax2.a[0] = 0;
> +  ax2.a[1] = 1;
> +  ax2.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +}
> +
> +
> +// Verify no warning for an unknown struct object.
> +void gaxp (struct Ax *p)
> +{
> +  p->a[0] = 0;
> +  p->a[3] = 3;
> +  p->a[9] = 9;
> +}
> +
> +
> +// Verify no warning for an extern struct object whose array may be
> +// initialized to any number of elements.
> +extern struct Ax axx;
> +
> +void gaxx (void)
> +{
> +  axx.a[0] = 0;
> +  axx.a[3] = 3;
> +  axx.a[9] = 9;
> +}
> +
> +// Exercise zero-length array members.
> +
> +struct A0
> +{
> +  char n;
> +  char a[0];                    // { dg-message "destination object" "note" }
> +};
> +
> +// Verify warning for a definition with no initializer.
> +struct A0 a0_;
> +
> +void ga0_ (void)
> +{
> +  a0_.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +  a0_.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +  a0_.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +}
> +
> +// Verify warning for access to a definition with an initializer that doesn't
> +// initialize the flexible array member.
> +struct A0 a00 = { 0 };
> +
> +void ga00 (void)
> +{
> +  a00.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +  a00.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +  a00.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +}
> +
> +// Verify warning for access to a definition with an initializer that
> +// initializes the flexible array member to empty.
> +struct A0 a00_ = { 0, { } };
> +
> +void ga00_ (void)
> +{
> +  a00_.a[0] = 0;                // { dg-warning "\\\[-Wstringop-overflow" }
> +  a00_.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
> +  a00_.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
> +}
> +
> +// The following are rejected with
> +//   error: too many initializers for 'char [0]'
> +// A0 a01 = { 1, { 0 } };
> +// A0 a02 = { 2, { 1, 0 } };
> +
> +
> +// Verify no warning for an unknown struct object.
> +void ga0p (struct A0 *p)
> +{
> +  p->a[0] = 0;
> +  p->a[3] = 3;
> +  p->a[9] = 9;
> +}
> +
> +
> +// Verify warning for an extern struct object which (unlike a true
> +// flexible array member) may not be initialized.
> +extern struct A0 a0x;
> +
> +void ga0x (void)
> +{
> +  a0x.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +  a0x.a[3] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +  a0x.a[9] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +}
> +
> +
> +// Exercise trailing one-element array members.
> +
> +struct A1
> +{
> +  char n;
> +  char a[1];                    // { dg-message "destination object" "note" }
> +};
> +
> +// Verify warning for a definition with no initializer.
> +struct A1 a1_;
> +
> +void ga1_ (void)
> +{
> +  a1_.a[0] = 0;
> +  a1_.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +  a1_.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +
> +  struct A1 a;
> +  a.a[0] = 0;
> +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
> +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
> +  sink (&a);
> +}
> +
> +// Verify warning for access to a definition with an initializer that doesn't
> +// initialize the one-element array member.
> +struct A1 a1__ = { 0 };
> +
> +void ga1__ (void)
> +{
> +  a1__.a[0] = 0;
> +  a1__.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +  a1__.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +
> +  struct A1 a = { 1 };
> +  a.a[0] = 0;
> +  a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
> +  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" }
> +  sink (&a);
> +}
> +
> +// Verify warning for access to a definition with an initializer that
> +// initializes the one-element array member to empty.
> +struct A1 a1_0 = { 0, { } };
> +
> +void ga1_0_ (void)
> +{
> +  a1_0.a[0] = 0;
> +  a1_0.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
> +  a1_0.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
> +
> +  struct A1 a = { 1, { } };
> +  a.a[0] = 0;
> +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
> +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
> +  sink (&a);
> +}
> +
> +// Verify warning for access to a definition with an initializer that
> +// initializes the one-element array member.
> +struct A1 a1_1 = { 0, { 1 } };
> +
> +void ga1_1 (void)
> +{
> +  a1_1.a[0] = 0;
> +  a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
> +  a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
> +
> +  struct A1 a = { 0, { 1 } };
> +  a.a[0] = 0;
> +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
> +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
> +  sink (&a);
> +}
> +
> +
> +// Verify no warning for an unknown struct object.
> +void ga1p (struct A1 *p)
> +{
> +  p->a[0] = 0;
> +  p->a[3] = 3;
> +  p->a[9] = 9;
> +}
> +
> +
> +// Verify warning for an extern struct object.  Similar to the zero-length
> +// array case, a one-element trailing array can be initialized to at most
> +// a single element.
> +extern struct A1 a1x;
> +
> +void ga1x (void)
> +{
> +  a1x.a[0] = 0;
> +  a1x.a[3] = 3;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +  a1x.a[9] = 9;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +}
> +
> +// Exercise interior one-element array members (verify they're not
> +// treated as trailing.
> +
> +struct A1i
> +{
> +  char n;
> +  char a[1];                    // { dg-message "destination object" }
> +  char x;
> +};
> +
> +// Verify warning for a definition with no initializer.
> +struct A1i a1i_;
> +
> +void ga1i_ (void)
> +{
> +  a1i_.a[0] = 0;
> +  a1i_.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
> +  a1i_.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
> +
> +  struct A1i a;
> +  a.a[0] = 1;
> +  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
> +  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" }
> +  sink (&a);
> +}
> +
> +// Verify warning for access to a definition with an initializer that doesn't
> +// initialize the one-element array member.
> +struct A1i a1i__ = { 0 };
> +
> +void ga1i__ (void)
> +{
> +  a1i__.a[0] = 0;
> +  a1i__.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
> +  a1i__.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
> +
> +  struct A1i a = { 0 };
> +  a.a[0] = 0;
> +  a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
> +  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" }
> +  sink (&a);
> +}
> +
> +// Verify warning for access to a definition with an initializer that
> +// initializes the one-element array member to empty.
> +struct A1 a1i_0 = { 0, { } };
> +
> +void ga1i_0_ (void)
> +{
> +  a1i_0.a[0] = 0;
> +  a1i_0.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow" }
> +  a1i_0.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow" }
> +
> +  struct A1 a = { 0, { } };
> +  a.a[0] = 0;
> +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
> +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
> +  sink (&a);
> +}
> +
> +// Verify warning for access to a definition with an initializer that
> +// initializes the one-element array member.
> +struct A1 a1i_1 = { 0, { 1 } };
> +
> +void ga1i_1 (void)
> +{
> +  a1i_1.a[0] = 0;
> +  a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow" }
> +  a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow" }
> +
> +  struct A1 a = { 0, { 1 } };
> +  a.a[0] = 1;
> +  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
> +  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" }
> +  sink (&a);
> +}
> +
> +
> +// Verify no warning for an unknown struct object.
> +void ga1ip (struct A1i *p)
> +{
> +  p->a[0] = 0;
> +  p->a[3] = 3;                  // { dg-warning "\\\[-Wstringop-overflow" }
> +  p->a[9] = 9;                  // { dg-warning "\\\[-Wstringop-overflow" }
> +}
> +
> +
> +// Verify no warning for an extern struct object.
> +extern struct A1i a1ix;
> +
> +void ga1ix (void)
> +{
> +  a1ix.a[0] = 0;
> +  a1ix.a[3] = 3;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +  a1ix.a[9] = 9;                 // { dg-warning "\\\[-Wstringop-overflow" }
> +}
> diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> index 7d29b5f48c7..cb687c69324 100644
> --- a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> +++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> @@ -189,8 +189,9 @@ void ga1__ (void)
>  
>    struct A1 a = { 1 };
>    a.a[0] = 0;
> +  // O2 vectorization regress Wstringop-overflow case (1), refer to pr102462.
>    a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
> -  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store } } }
>    sink (&a);
>  }
>  
> @@ -206,8 +207,9 @@ void ga1_0_ (void)
>  
>    struct A1 a = { 1, { } };
>    a.a[0] = 0;
> +  // O2 vectorization regress Wstringop-overflow case (1), refer to PR102462.
>    a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
> -  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store } } }
>    sink (&a);
>  }
>  
> @@ -221,10 +223,11 @@ void ga1_1 (void)
>    a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
>    a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
>  
> -  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> +// O2 vectorization regress Wstringop-overflow case (2), refer to PR102706
> +  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v4qi_store } } }
>    a.a[0] = 0;
> -  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> -  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store } } }
> +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store } } }
>    sink (&a);
>  }
>  
> @@ -288,8 +291,9 @@ void ga1i__ (void)
>  
>    struct A1i a = { 0 };
>    a.a[0] = 0;
> +  // O2 vectorization regress Wstringop-overflow case (1), refer to PR102462
>    a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
> -  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store } } }
>    sink (&a);
>  }
>  
> @@ -305,8 +309,9 @@ void ga1i_0_ (void)
>  
>    struct A1 a = { 0, { } };
>    a.a[0] = 0;
> +  // O2 vectorization regress Wstringop-overflow case (1), refer to PR102462
>    a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
> -  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v2qi_store } } }
>    sink (&a);
>  }
>  
> @@ -320,10 +325,11 @@ void ga1i_1 (void)
>    a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow" }
>    a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow" }
>  
> -  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> +  // O2 vectorization regress Wstringop-overflow case (1), refer to PR102462
> +  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v4qi_store } } }
>    a.a[0] = 1;
> -  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> -  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store } } }
> +  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store } } }
>    sink (&a);
>  }
>  
> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> new file mode 100644
> index 00000000000..da179a2c0f5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> @@ -0,0 +1,364 @@
> +/* PR middle-end/91647 - missing -Warray-bounds accessing a zero-length array
> +   of a declared object
> +   { dg-do "compile" }
> +   { dg-options "-O2 -Wall -fno-tree-vectorize" }
> +   { dg-require-effective-target alloca } */
> +
> +typedef __INT16_TYPE__ int16_t;
> +typedef __INT32_TYPE__ int32_t;
> +
> +void sink (void*);
> +
> +/* Exercise a true flexible member.  */
> +
> +struct AX
> +{
> +  int32_t n;
> +  int16_t ax[];     // { dg-message "while referencing 'ax'" "member" }
> +};
> +
> +static void warn_ax_local (struct AX *p)
> +{
> +  p->ax[0] = 0;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->ax[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void nowarn_ax_extern (struct AX *p)
> +{
> +  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
> +}
> +
> +static void warn_ax_local_buf (struct AX *p)
> +{
> +  p->ax[0] = 4; p->ax[1] = 5;
> +
> +  p->ax[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->ax[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->ax[4] = 8;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_ax_extern_buf (struct AX *p)
> +{
> +  p->ax[0] = 9; p->ax[1] = 10; p->ax[2] = 11;
> +
> +  p->ax[3] = 12;    // { dg-warning "\\\[-Warray-bounds" }
> +  p->ax[4] = 13;    // { dg-warning "\\\[-Warray-bounds" }
> +  p->ax[5] = 14;    // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void nowarn_ax_extern_bufx (struct AX *p)
> +{
> +  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
> +}
> +
> +static void nowarn_ax_ref (struct AX *p)
> +{
> +  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
> +}
> +
> +void test_ax (struct AX *p, unsigned n)
> +{
> +  {
> +    struct AX sax;  // { dg-message "defined here" "struct definition" }
> +    warn_ax_local (&sax);
> +    sink (&sax);
> +  }
> +
> +  {
> +    extern
> +      struct AX xsax;
> +    nowarn_ax_extern (&xsax);
> +    sink (&xsax);
> +  }
> +
> +  {
> +    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
> +    char ax_buf_p2[sizeof (struct AX) + 2 * sizeof (int16_t)];
> +    warn_ax_local_buf ((struct AX*) ax_buf_p2);
> +    sink (ax_buf_p2);
> +  }
> +
> +  {
> +    /* Verify out-of-bounds access to the extern BUF with a known
> +       bound is diagnosed.  */
> +    extern char ax_buf_p3[sizeof (struct AX) + 3 * sizeof (int16_t)];
> +    warn_ax_extern_buf ((struct AX*) ax_buf_p3);
> +    sink (ax_buf_p3);
> +  }
> +
> +  {
> +    /* Verify that accesses to BUFX with an unknown bound are not
> +       diagnosed.  */
> +    extern char bufx[];
> +    nowarn_ax_extern_bufx ((struct AX*) bufx);
> +    sink (bufx);
> +  }
> +
> +  {
> +    /* Verify that accesses to BUFN with a runtime bound are not
> +       diagnosed.  */
> +    char bufn[n];
> +    nowarn_ax_extern_bufx ((struct AX*) bufn);
> +    sink (bufn);
> +  }
> +
> +  nowarn_ax_ref (p);
> +}
> +
> +
> +/* Exercise a zero-length trailing member array.  It's the same as above
> +   except that extern declarations with no definitions are considered to
> +   have zero elements (they can't be initialized to have any).  */
> +
> +struct A0
> +{
> +  int32_t n;
> +  int16_t a0[0];    // { dg-message "while referencing 'a0'" "member" }
> +};
> +
> +static void warn_a0_local (struct A0 *p)
> +{
> +  p->a0[0] = 0;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a0[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a0_extern (struct A0 *p)
> +{
> +  p->a0[0] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a0[1] = 3;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a0_local_buf (struct A0 *p)
> +{
> +  p->a0[0] = 4; p->a0[1] = 5;
> +
> +  p->a0[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a0[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a0[4] = 8;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a0_extern_buf (struct A0 *p)
> +{
> +  p->a0[0] = 9; p->a0[1] = 10; p->a0[2] = 11;
> +
> +  p->a0[3] = 12;    // { dg-warning "\\\[-Warray-bounds" }
> +  p->a0[4] = 13;    // { dg-warning "\\\[-Warray-bounds" }
> +  p->a0[5] = 14;    // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void nowarn_a0_extern_bufx (struct A0 *p)
> +{
> +  p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
> +}
> +
> +static void nowarn_a0_ref (struct A0 *p)
> +{
> +  p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
> +}
> +
> +void test_a0 (struct A0 *p, unsigned n)
> +{
> +  {
> +    struct A0 sa0;  // { dg-message "defined here" "struct definition" }
> +    warn_a0_local (&sa0);
> +    sink (&sa0);
> +  }
> +
> +  {
> +    extern
> +      struct A0 xsa0;  // { dg-message "defined here" "struct definition" }
> +    warn_a0_extern (&xsa0);
> +    sink (&xsa0);
> +  }
> +
> +  {
> +    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
> +    char a0_buf_p2[sizeof (struct A0) + 2 * sizeof (int16_t)];
> +    warn_a0_local_buf ((struct A0*) a0_buf_p2);
> +    sink (a0_buf_p2);
> +  }
> +
> +  {
> +    /* Verify out-of-bounds access to the extern BUF with a known
> +       bound is diagnosed.  */
> +    extern char a0_buf_p3[sizeof (struct A0) + 3 * sizeof (int16_t)];
> +    warn_a0_extern_buf ((struct A0*) a0_buf_p3);
> +    sink (a0_buf_p3);
> +  }
> +
> +  {
> +    /* Verify that accesses to BUFX with an unknown bound are not
> +       diagnosed.  */
> +    extern char bufx[];
> +    nowarn_a0_extern_bufx ((struct A0*) bufx);
> +    sink (bufx);
> +  }
> +
> +  {
> +    /* Verify that accesses to BUFN with a runtime bound are not
> +       diagnosed.  */
> +    char bufn[n];
> +    nowarn_a0_extern_bufx ((struct A0*) bufn);
> +    sink (bufn);
> +  }
> +
> +  nowarn_a0_ref (p);
> +}
> +
> +
> +/* Exercise a one-element trailing member array.  It's the same as above
> +   except that it has exactly one element.  */
> +
> +struct A1
> +{
> +  int32_t n;
> +  int16_t a1[1];    // { dg-message "while referencing 'a1'" }
> +};
> +
> +static void warn_a1_local_noinit (struct A1 *p)
> +{
> +  p->a1[0] = 0;
> +  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a1_extern (struct A1 *p)
> +{
> +  p->a1[0] = 0;
> +  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a1_init (struct A1 *p)
> +{
> +  p->a1[0] = 0;
> +  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a1_local_buf (struct A1 *p)
> +{
> +  p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3;
> +
> +  p->a1[4] = 4;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a1_extern_buf (struct A1 *p)
> +{
> +  p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3; p->a1[4] = 4;
> +
> +  p->a1[5] = 5;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void nowarn_a1_extern_bufx (struct A1 *p)
> +{
> +  p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
> +}
> +
> +static void nowarn_a1_ref (struct A1 *p)
> +{
> +  p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
> +}
> +
> +void test_a1 (struct A1 *p, unsigned n)
> +{
> +  {
> +    struct A1 a1;
> +    warn_a1_local_noinit (&a1);
> +    sink (&a1);
> +  }
> +
> +  {
> +    extern struct A1 a1x;
> +    warn_a1_extern (&a1x);
> +    sink (&a1x);
> +}
> +  {
> +    struct A1 a1 = { 0, { 1 } };
> +    warn_a1_init (&a1);
> +    sink (&a1);
> +  }
> +
> +  {
> +    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
> +    char buf_p2[sizeof (struct A1) + 2 * sizeof (int16_t)];
> +    warn_a1_local_buf ((struct A1*) buf_p2);
> +    sink (buf_p2);
> +  }
> +
> +  {
> +    /* Verify out-of-bounds access to the extern BUF with a known
> +       bound is diagnosed.  */
> +    extern char a1_buf_p3[sizeof (struct A1) + 3 * sizeof (int16_t)];
> +    warn_a1_extern_buf ((struct A1*) a1_buf_p3);
> +    sink (a1_buf_p3);
> +  }
> +
> +  {
> +    /* Verify that accesses to BUFX with an unknown bound are not
> +       diagnosed.  */
> +    extern char bufx[];
> +    nowarn_a1_extern_bufx ((struct A1*) bufx);
> +    sink (bufx);
> +  }
> +
> +  {
> +    /* Verify that accesses to BUFN with a runtime bound are not
> +       diagnosed.  */
> +    char bufn[n];
> +    nowarn_a1_extern_bufx ((struct A1*) bufn);
> +    sink (bufn);
> +  }
> +
> +  nowarn_a1_ref (p);
> +}
> +
> +
> +/* Exercise a two-element trailing member array.  It's treated
> +   the same as an interior array member.  */
> +
> +struct A2
> +{
> +  int32_t n;
> +  int16_t a2[2];    // { dg-message "while referencing 'a2'" }
> +};
> +
> +static void warn_a2_noinit (struct A2 *p)
> +{
> +  p->a2[0] = 0; p->a2[1] = 1;
> +
> +  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a2_init (struct A2 *p)
> +{
> +  p->a2[0] = 0; p->a2[1] = 1;
> +
> +  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a2[9] = 9;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a2_ref (struct A2 *p)
> +{
> +  p->a2[0] = 0; p->a2[1] = 1;
> +
> +  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a2[9] = 9;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +void test_a2 (struct A2 *p)
> +{
> +  {
> +    struct A2 a2;
> +    warn_a2_noinit (&a2);
> +    sink (&a2);
> +  }
> +
> +  {
> +    struct A2 a2 = { 0, { 1, 2 } };
> +    warn_a2_init (&a2);
> +    sink (&a2);
> +  }
> +
> +  warn_a2_ref (p);
> +}
> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48.c b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> index 13373d1e99e..27dd879de5c 100644
> --- a/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> @@ -30,7 +30,8 @@ static void nowarn_ax_extern (struct AX *p)
>  
>  static void warn_ax_local_buf (struct AX *p)
>  {
> -  p->ax[0] = 4; p->ax[1] = 5;
> +  // Refer to 102706
> +  p->ax[0] = 4; p->ax[1] = 5;  // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v2hi_store &&  { ! vect_slp_v4hi_store } } } }
>  
>    p->ax[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
>    p->ax[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> @@ -130,7 +131,8 @@ static void warn_a0_extern (struct A0 *p)
>  
>  static void warn_a0_local_buf (struct A0 *p)
>  {
> -  p->a0[0] = 4; p->a0[1] = 5;
> +  // Refer to 102706
> +  p->a0[0] = 4; p->a0[1] = 5;  // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v2hi_store && { ! vect_slp_v4hi_store } } } }
>  
>    p->a0[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
>    p->a0[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c b/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> new file mode 100644
> index 00000000000..24bc318f113
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> @@ -0,0 +1,61 @@
> +/* PR middle-end/92333 - missing variable name referencing VLA in warnings
> +   PR middle-end/82608 - missing -Warray-bounds on an out-of-bounds VLA index
> +   { dg-do compile }
> +   { dg-options "-O2 -Wall -fno-tree-vectorize" }  */
> +
> +void sink (void*);
> +
> +void test_char_vla_location (void)
> +{
> +  unsigned nelts = 7;
> +
> +  char vla[nelts];    // { dg-message "declared here|while referencing" }
> +
> +  vla[0] = __LINE__;
> +  vla[nelts] = 0;     // { dg-warning "\\\[-Warray-bounds" }
> +
> +  sink (vla);
> +}
> +
> +void test_int_vla_location (void)
> +{
> +  unsigned nelts = 7;
> +
> +  int vla[nelts];     // { dg-message "declared here|while referencing" }
> +
> +  vla[0] = __LINE__;
> +  vla[nelts] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> +
> +  sink (vla);
> +}
> +
> +void test_struct_char_vla_location (void)
> +{
> +  unsigned nelts = 7;
> +
> +  struct {
> +    char cvla[nelts]; // { dg-message "declared here|while referencing" }
> +  } s;
> +
> +  s.cvla[0] = __LINE__;
> +  s.cvla[nelts - 1] = 0;
> +  s.cvla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
> +
> +  sink (&s);
> +}
> +
> +
> +void test_struct_int_vla_location (void)
> +{
> +  unsigned nelts = 7;
> +
> +  struct {
> +    int ivla[nelts];  // { dg-message "declared here|while referencing" }
> +  } s;
> +
> +  s.ivla[0] = __LINE__;
> +  s.ivla[nelts - 1] = 0;
> +  s.ivla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
> +
> +  sink (&s);
> +}
> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-51.c b/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> index de60d87ab95..cc92a0fd500 100644
> --- a/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> @@ -39,7 +39,8 @@ void test_struct_char_vla_location (void)
>    } s;
>  
>    s.cvla[0] = __LINE__;
> -  s.cvla[nelts - 1] = 0; // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> +  // O2 vectorization regress Wstringop-overflow case (2), refer to pr102706.
> +  s.cvla[nelts - 1] = 0; // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v2qi_store } } }
>    s.cvla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
>  
>    sink (&s);
> diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c b/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> new file mode 100644
> index 00000000000..0c8fdd11ec9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> @@ -0,0 +1,89 @@
> +/* PR c/50584 - No warning for passing small array to C99 static array
> +   declarator
> +   { dg-do compile }
> +   { dg-options "-Wall -Warray-parameter=1" } */
> +
> +/* Verify that at level 1 mismatches in the bounds of ordinary array
> +   parameters don't trigger -Warray-parameter.  */
> +void fax (int[]);
> +void fax (int[0]);
> +void fax (int[1]);
> +void fax (int[2]);
> +void fax (int[3]);
> +
> +/* Same as above but starting with an array with a specified bound.  */
> +void gax (int[3]);
> +void gax (int[2]);
> +void gax (int[1]);
> +void gax (int[0]);
> +void gax (int[]);
> +
> +/* Same for multidimensional arrays.  */
> +void fax_y (int[][3]);
> +void fax_y (int[0][3]);
> +void fax_y (int[1][3]);
> +void fax_y (int[2][3]);
> +void fax_y (int[3][3]);
> +
> +/* Same as above but starting with an array with a specified bound.  */
> +void gax_y (int[3][5]);
> +void gax_y (int[2][5]);
> +void gax_y (int[1][5]);
> +void gax_y (int[0][5]);
> +void gax_y (int[][5]);
> +
> +/* Exercise VLAs with a mismatch in the bound for an ordinary array.  */
> +void fvlax_y (int n, int[][n]);
> +void fvlax_y (int n, int[0][n]);
> +void fvlax_y (int n, int[1][n]);
> +void fvlax_y (int n, int[2][n]);
> +void fvlax_y (int n, int[3][n]);
> +
> +void fvlaxn_y (int n, int[][n]);
> +void fvlaxn_y (int n, int[0][n]);
> +void fvlaxn_y (int n, int[1][n]);
> +void fvlaxn_y (int n, int[2][n]);
> +void fvlaxn_y (int n, int[3][n]);
> +
> +void fvlaxx_y (int[][*]);
> +void fvlaxx_y (int[0][*]);
> +void fvlaxx_y (int[1][*]);
> +void fvlaxx_y (int[2][*]);
> +void fvlaxx_y (int[3][*]);
> +
> +/* Verify that mismatches in the bounds of array parameters declared
> +   static do trigger -Warray-parameter.  */
> +void fas1 (int[static 1]);    // { dg-message "previously declared as 'int\\\[static 1]'" }
> +void fas1 (int[static 2]);    // { dg-warning "\\\[-Warray-parameter=" }
> +
> +
> +/* Also verify that -Warray-bounds doesn't trigger for ordinary array
> +   parameters...  */
> +#pragma GCC optimize ("2,no-tree-vectorize")
> +
> +__attribute__ ((noipa)) void
> +gca3 (char a[3])
> +{
> +  a[0] = 0; a[1] = 1; a[2] = 2; a[3] = 3;
> +}
> +
> +__attribute__ ((noipa)) void
> +gia3 (int a[3])
> +{
> +  a[0] = 0; a[1] = 1; a[2] = 2; a[3] = 3;
> +}
> +
> +/* ...but does for static arrays.  */
> +__attribute__ ((noipa)) void
> +gcas3 (char a[static 3])
> +{
> +  a[0] = 0; a[1] = 1; a[2] = 2;
> +  a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +__attribute__ ((noipa)) void
> +gias3 (int a[static 3])
> +{
> +  a[0] = 0; a[1] = 1; a[2] = 2;
> +  a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
> +}
> diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3.c b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> index e8a269c85c6..1068707973f 100644
> --- a/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> +++ b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> @@ -77,7 +77,8 @@ gia3 (int a[3])
>  __attribute__ ((noipa)) void
>  gcas3 (char a[static 3])
>  {
> -  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> +  // O2 vectorization regress Wstringop-overflow case (2), refer to pr102706.
> +  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v4qi_store } } }
>    a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
>  }
>  
> diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> new file mode 100644
> index 00000000000..c7b5479dc07
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> @@ -0,0 +1,56 @@
> +/* Test to verify that past-the-end multibyte writes via lvalues of wider
> +   types than char are diagnosed.
> +   { dg-do compile }
> +   { dg-require-effective-target int32plus }
> +   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds" }  */
> +
> +typedef __INT16_TYPE__  int16_t;
> +typedef __INT32_TYPE__  int32_t;
> +typedef __INT64_TYPE__  int64_t;
> +typedef __SIZE_TYPE__   size_t;
> +
> +void* memcpy (void*, const void*, size_t);
> +char* strcpy (char*, const char*);
> +
> +char a4[4], a8[8], a16[16];
> +
> +const char s4[] = "1234";
> +const char t4[] = "4321";
> +
> +void test_memcpy_cond (int i)
> +{
> +  char *p = a4 + 1;
> +  const char *q = i ? s4 : t4;
> +  // On strictly aligned target the call below is left unchanged and
> +  // triggers (inaccurately) a -Warray-bounds.  The test suppresses
> +  // the warning above, which then lets -Wstringop-overrflow detect
> +  // the overflow just before expansion.
> +  // On other targets it's transformed into a store of a 4-byte integer
> +  // which is detected by -Wstringop-overrflow in the strlen pass (i.e.,
> +  // before it gets to expansion).
> +  memcpy (p, q, 4);         // { dg-warning "writing 4 bytes into a region of size 3" }
> +}
> +
> +
> +void test_int16 (void)
> +{
> +  char *p = a4 + 1;
> +  *(int16_t*)p = 0;
> +  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a region of size 1" }
> +}
> +
> +
> +void test_int32 (void)
> +{
> +  char *p = a8 + 3;
> +  *(int32_t*)p = 0;
> +  *(int32_t*)(p + 2) = 0;   // { dg-warning "writing 4 bytes into a region of size 3" }
> +}
> +
> +
> +void test_int64 (void)
> +{
> +  char *p = a16 + 5;
> +  *(int64_t*)p = 0;
> +  *(int64_t*)(p + 5) = 0;   // { dg-warning "writing 8 bytes into a region of size 6" }
> +}
> diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> index 7683084e46e..6ad9444bc27 100644
> --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> @@ -36,8 +36,9 @@ void test_memcpy_cond (int i)
>  void test_int16 (void)
>  {
>    char *p = a4 + 1;
> -  *(int16_t*)p = 0;    // { dg-warning "writing 4 bytes into a region of size 3" "" { target { i?86-*-* x86_64-*-* } } }
> -  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a region of size 1" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  // O2 vectorization regress Wstringop-overflow case (2), refer to pr102706.
> +  *(int16_t*)p = 0;    // { dg-warning "writing 4 bytes into a region of size 3" "" { target { vect_slp_v2hi_store } } }
> +  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a region of size 1" "" { xfail { vect_slp_v2hi_store } } }
>  }
>  
>  
> diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> new file mode 100644
> index 00000000000..b177543b186
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> @@ -0,0 +1,59 @@
> +/* PR middle-end/92312 - bogus -Wstringop-overflow storing into a trailing
> +   array backed by larger buffer
> +   { dg-do compile }
> +   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds" } */
> +
> +struct S0 { char a, b[0]; };
> +
> +void sink (void*);
> +
> +void test_memset_zero_length (void)
> +{
> +  char a[3];
> +  struct S0 *p = (struct S0*)a;
> +  p->a = 0;
> +  __builtin_memset (p->b, 0, 2);
> +  sink (p);
> +
> +  __builtin_memset (p->b, 0, 3);    // { dg-warning "\\\[-Wstringop-overflow" }
> +  sink (p);
> +}
> +
> +void test_store_zero_length (int i)
> +{
> +  char a[3];
> +  struct S0 *p = (struct S0*)a;
> +  p->a = 0;
> +  p->b[0] = 0;
> +  p->b[1] = 1;                      // { dg-bogus "\\\[-Wstringop-overflow" }
> +  p->b[2] = 2;                      // { dg-warning "\\\[-Wstringop-overflow" }
> +  p->b[i] = 2;
> +  sink (p);
> +}
> +
> +
> +struct Sx { char a, b[]; };
> +
> +void test_memset_flexarray (int i)
> +{
> +  char a[3];
> +  struct Sx *p = (struct Sx*)a;
> +  p->a = 0;
> +  __builtin_memset (p->b, 0, 2);
> +  sink (p);
> +
> +  __builtin_memset (p->b, 0, 3);    // { dg-warning "\\\[-Wstringop-overflow" }
> +  sink (p);
> +}
> +
> +void test_store_flexarray (int i)
> +{
> +  char a[3];
> +  struct Sx *p = (struct Sx*)a;
> +  p->a = 0;
> +  p->b[0] = 0;
> +  p->b[1] = 1;                      // { dg-bogus "\\\[-Wstringop-overflow" }
> +  p->b[2] = 1;                      // { dg-warning "\\\[-Wstringop-overflow" }
> +  p->b[i] = 2;
> +  sink (p);
> +}
> diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> index d88bde9c740..8d2bfe697a5 100644
> --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> @@ -23,10 +23,11 @@ void test_store_zero_length (int i)
>  {
>    char a[3];
>    struct S0 *p = (struct S0*)a;
> -  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> +  // O2 vectorization regress Wstringop-overflow case (2), refer to pr102706.
> +  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v4qi_store } } }
>    p->b[0] = 0;
>    p->b[1] = 1;                      // { dg-bogus "\\\[-Wstringop-overflow" }
> -  p->b[2] = 2;                      // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  p->b[2] = 2;                      // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store } } }
>    p->b[i] = 2;
>    sink (p);
>  }
> @@ -50,10 +51,11 @@ void test_store_flexarray (int i)
>  {
>    char a[3];
>    struct Sx *p = (struct Sx*)a;
> -  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> +  // O2 vectorization regress Wstringop-overflow case (2), refer to pr102706.
> +  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "" { target { vect_slp_v4qi_store } } }
>    p->b[0] = 0;
>    p->b[1] = 1;                      // { dg-bogus "\\\[-Wstringop-overflow" }
> -  p->b[2] = 1;                      // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  p->b[2] = 1;                      // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store } } }
>    p->b[i] = 2;
>    sink (p);
>  }
> diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> index 09df0004991..04e91afb8bc 100644
> --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> @@ -58,11 +58,18 @@ void warn_comp_lit_zero (void)
>  void warn_comp_lit (void)
>  {
>    *(AC2*)a1 = Ac2;      // { dg-warning "writing 2 bytes into a region of size 1" "pr101475" { xfail *-*-* } }
> -  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 2" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> -  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 3" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> -  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 4" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> -  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 7" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> -  *(AC16*)a15 = Ac16;   // { dg-warning "writing 16 bytes into a region of size 15" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> +  // After vectorization, below codes are optimized to
> +  // MEM <vector(4) char> [(char *)&a2] = { 0, 1, 2, 3 };
> +  // MEM <vector(4) char> [(char *)&a3] = { 0, 1, 2, 3 };
> +  // MEM <vector(8) char> [(char *)&a4] = { 0, 1, 2, 3, 4, 5, 6, 7 };
> +  // MEM <vector(8) char> [(char *)&a7] = { 0, 1, 2, 3, 4, 5, 6, 7 };
> +  // MEM <vector(16) char> [(char *)&a15] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
> +  // and warning should be expected, refer to PR102722.
> +  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 2" "pr101475" { xfail { ! { vect_slp_v4qi_store } } } }
> +  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 3" "pr101475" { xfail { ! { vect_slp_v4qi_store } } } }
> +  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 4" "pr101475" { xfail { ! { vect_slp_v8qi_store } } } }
> +  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 7" "pr101475" { xfail { ! { vect_slp_v8qi_store } } } }
> +  *(AC16*)a15 = Ac16;   // { dg-warning "writing 16 bytes into a region of size 15" "pr101475" { xfail { ! { vect_slp_v16qi_store } } } }
>  }
>  
>  void warn_aggr_decl (void)
> diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> new file mode 100644
> index 00000000000..d000b587a65
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> @@ -0,0 +1,147 @@
> +/* Verify warnings and notes for MAX_EXPRs involving either pointers
> +   to distinct objects or one to a known object and the other to
> +   an unknown one.  Unlike for the same object, for unrelated objects
> +   the expected warnings and notes are the same as for MIN_EXPR: when
> +   the order of the objects in the address space cannot be determined
> +   the larger of them is assumed to be used.  (This is different for
> +   distinct struct members where the order is given.)
> +   The relational expressions are strictly invalid but that should be
> +   diagnosed by a separate warning.
> +   { dg-do compile }
> +   { dg-options "-O2 -Wno-array-bounds -fno-tree-vectorize" } */
> +
> +#define MAX(p, q) ((p) > (q) ? (p) : (q))
> +
> +/* Verify that even for MAX_EXPR and like for MIN_EXPR, the note points
> +   to the larger of the two objects and mentions the offset into it
> +   (although the offset might be better included in the warning).  */
> +extern char a3[3];
> +extern char a5[5];  // { dg-message "at offset 5 into destination object 'a5' of size 5" "note" }
> +
> +void max_a3_a5 (int i)
> +{
> +  char *p = a3 + i;
> +  char *q = a5 + i;
> +
> +  /* The relational expression below is invalid and should be diagnosed
> +     by its own warning independently of -Wstringop-overflow.  */
> +  char *d = MAX (p, q);
> +
> +  d[2] = 0;
> +  d[3] = 0;
> +  d[4] = 0;
> +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
> +}
> +
> +
> +// Same as above but with the larger array as the first MAX_EXPR operand.
> +extern char b4[4];
> +extern char b6[6];  // { dg-message "at offset 6 into destination object 'b6' of size 6" "note" }
> +
> +void max_b6_b4 (int i)
> +{
> +  char *p = b6 + i;
> +  char *q = b4 + i;
> +  char *d = MAX (p, q);
> +
> +  d[3] = 0;
> +  d[4] = 0;
> +  d[5] = 0;
> +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
> +}
> +
> +
> +/* Same as above but with the first MAX_EXPR operand pointing to an unknown
> +   object.  */
> +extern char c7[7];  // { dg-message "at offset 7 into destination object 'c7' of size 7" "note" }
> +
> +void max_p_c7 (char *p, int i)
> +{
> +  char *q = c7 + i;
> +  char *d = MAX (p, q);
> +
> +  d[6] = 0;
> +  d[7] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
> +}
> +
> +
> +/* Same as above but with the second MIN_EXPR operand pointing to an unknown
> +   object.  */
> +extern char d8[8];  // { dg-message "at offset 8 into destination object 'd8' of size 8" "note" }
> +
> +void max_d8_p (char *q, int i)
> +{
> +  char *p = d8 + i;
> +  char *d = MAX (p, q);
> +
> +  d[7] = 0;
> +  d[8] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
> +}
> +
> +
> +struct A3_5
> +{
> +  char a3[3];  // { dg-message "at offset 3 into destination object 'a3' of size 3" "pr??????" { xfail *-*-* } }
> +  char a5[5];
> +};
> +
> +void max_A3_A5 (int i, struct A3_5 *pa3_5)
> +{
> +  char *p = pa3_5->a3 + i;
> +  char *q = pa3_5->a5 + i;
> +
> +  char *d = MAX (p, q);
> +  d[2] = 0;
> +  d[3] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "pr??????" { xfail *-*-* } }
> +  d[4] = 0;
> +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
> +}
> +
> +
> +struct B4_B6
> +{
> +  char b4[4];
> +  char b6[6];       // { dg-message "at offset 6 into destination object 'b6' of size 6" "note" }
> +};
> +
> +void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
> +{
> +  char *p = pb4_b6->b6 + i;
> +  char *q = pb4_b6->b4 + i;
> +  char *d = MAX (p, q);
> +
> +  d[3] = 0;
> +  d[4] = 0;
> +  d[5] = 0;
> +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
> +}
> +
> +
> +struct C7
> +{
> +  char c7[7];       // { dg-message "at offset 7 into destination object 'c7' of size 7" "note" }
> +};
> +
> +void max_p_C7 (char *p, int i, struct C7 *pc7)
> +{
> +  char *q = pc7->c7 + i;
> +  char *d = MAX (p, q);
> +
> +  d[6] = 0;
> +  d[7] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
> +}
> +
> +
> +struct D8
> +{
> +  char d8[8];       // { dg-message "at offset 8 into destination object 'd8' of size 8" "note" }
> +};
> +
> +void max_D8_p (char *q, int i, struct D8 *pd8)
> +{
> +  char *p = pd8->d8 + i;
> +  char *d = MAX (p, q);
> +
> +  d[7] = 0;
> +  d[8] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
> +}
> diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> index 0c7b53ccc0b..037e66c2769 100644
> --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> @@ -27,10 +27,11 @@ void max_a3_a5 (int i)
>       by its own warning independently of -Wstringop-overflow.  */
>    char *d = MAX (p, q);
>  
> -  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "" { target { i?86-*-* x86_64-*-* } } }
> +  // O2 vectorization regress Wstringop-overflow case (2), refer to pr102706.
> +  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "" { target { vect_slp_v4qi_store } } }
>    d[3] = 0;
>    d[4] = 0;
> -  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { vect_slp_v4qi_store } } }
>  }
>  
>  
> @@ -44,10 +45,11 @@ void max_b6_b4 (int i)
>    char *q = b4 + i;
>    char *d = MAX (p, q);
>  
> -  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "" { target { i?86-*-* x86_64-*-* } } }
> +  // O2 vectorization regress Wstringop-overflow case (2), refer to pr102706.
> +  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "" { target { vect_slp_v4qi_store } } }
>    d[4] = 0;
>    d[5] = 0;
> -  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { vect_slp_v4qi_store } } }
>  }
>  
>  
> @@ -82,7 +84,7 @@ void max_d8_p (char *q, int i)
>  struct A3_5
>  {
>    char a3[3];  // { dg-message "at offset 3 into destination object 'a3' of size 3" "pr??????" { xfail *-*-* } }
> -  char a5[5];  // { dg-message "at offset 5 into destination object 'a5' of size 5" "note" { xfail { i?86-*-* x86_64-*-* } } }
> +  char a5[5];  // { dg-message "at offset 5 into destination object 'a5' of size 5" "note" { xfail { vect_slp_v4qi_store } } }
>  };
>  
>  void max_A3_A5 (int i, struct A3_5 *pa3_5)
> @@ -91,18 +93,20 @@ void max_A3_A5 (int i, struct A3_5 *pa3_5)
>    char *q = pa3_5->a5 + i;
>  
>    char *d = MAX (p, q);
> -
> +  // After vectorization, below codes are vectorized to
> +  // MEM <vector(4) char> [(char *)&d + 3] = { 0, 0, 0, 0 };
> +  // refer to pr102697.
>    d[2] = 0;
>    d[3] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "pr??????" { xfail *-*-* } }
>    d[4] = 0;
> -  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { vect_slp_v4qi_store } } }
>  }
>  
>  
>  struct B4_B6
>  {
>    char b4[4];
> -  char b6[6];       // { dg-message "at offset \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6" "note" { xfail { i?86-*-* x86_64-*-* } } }
> +  char b6[6];       // { dg-message "at offset \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6" "note" { xfail { vect_slp_v4qi_store } } }
>  };
>  
>  void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
> @@ -110,11 +114,13 @@ void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
>    char *p = pb4_b6->b6 + i;
>    char *q = pb4_b6->b4 + i;
>    char *d = MAX (p, q);
> -
> +  // After vectorization, below codes are vectorized to
> +  // MEM <vector(4) char> [(char *)&d + 3] = { 0, 0, 0, 0 };
> +  // refer to pr102697.
>    d[3] = 0;
>    d[4] = 0;
>    d[5] = 0;
> -  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { vect_slp_v4qi_store } } }
>  }
>  
>  
> diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
> index 9ebca7ac007..c30831ea91d 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -7580,6 +7580,135 @@ proc check_effective_target_vect_element_align_preferred { } {
>  		   && [check_effective_target_vect_variable_length] }]
>  }
>  
> +# Return true if vectorization of v2qi/v4qi/v8qi/v16qi/v2hi store is enabed.
> +# Return zero if the desirable pattern isn't found.
> +# It's used by Warray-bounds/Wstringop-overflow testcases which are
> +# regressed by O2 vectorization, refer to PR102697/PR102462/PR102706
> +proc check_vect_slp_vnqihi_store_usage { pattern } {
> +    global tool
> +
> +    return [check_cached_effective_target slp_vnqihi_store_usage {
> +      set result [check_compile slp_vnqihi_store_usage assembly {
> +	  char a[16] __attribute__ ((aligned (16)));
> +	  void
> +	  foo ()
> +	  {
> +	      a[0] = 0;
> +	      a[1] = 1;
> +	      a[2] = 2;
> +	      a[3] = 3;
> +	      a[4] = 4;
> +	      a[5] = 5;
> +	      a[6] = 6;
> +	      a[7] = 7;
> +	  }
> +
> +	  void
> +	  foo1 ()
> +	  {
> +	      a[0] = 0;
> +	      a[1] = 1;
> +	      a[2] = 2;
> +	      a[3] = 3;
> +	      a[4] = 4;
> +	      a[5] = 5;
> +	      a[6] = 6;
> +	      a[7] = 7;
> +	      a[8] = 8;
> +	      a[9] = 9;
> +	      a[10] = 10;
> +	      a[11] = 11;
> +	      a[12] = 12;
> +	      a[13] = 13;
> +	      a[14] = 14;
> +	      a[15] = 15;
> +	  }
> +
> +	  void
> +	  foo2 ()
> +	  {
> +	      a[0] = 0;
> +	      a[1] = 1;
> +	      a[2] = 2;
> +	      a[3] = 3;
> +	  }
> +
> +	  void
> +	  foo3 ()
> +	  {
> +	      a[0] = 0;
> +	      a[1] = 1;
> +	  }
> +
> +	  short b[4] __attribute__((aligned(8)));
> +	  void
> +	  foo4 ()
> +	  {
> +	      b[0] = 0;
> +	      b[1] = 1;
> +	  }
> +
> +	  void
> +	  foo5 ()
> +	  {
> +	      b[0] = 0;
> +	      b[1] = 1;
> +	      b[2] = 2;
> +	      b[3] = 3;
> +	  }
> +
> +      } "-O2 -fopt-info-all" ]
> +
> +      # Get compiler emitted messages and delete generated file.
> +      set lines [lindex $result 0]
> +      set output [lindex $result 1]
> +      remote_file build delete $output
> +
> +      # Capture the vectorized info of v2qi, set it to zero if not found.
> +	if { ![regexp $pattern $lines whole val] } then {
> +	  set val 0
> +      }
> +
> +      return $val
> +    }]
> +}
> +
> +# Return the true if target support vectorization of v2qi store.
> +proc check_effective_target_vect_slp_v2qi_store { } {
> +    set pattern {add new stmt: MEM <vector\(2\) char>}
> +    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
> +}
> +
> +# Return the true if target support vectorization of v4qi store.
> +proc check_effective_target_vect_slp_v4qi_store { } {
> +    set pattern {add new stmt: MEM <vector\(4\) char>}
> +    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
> +}
> +
> +# Return the true if target support vectorization of v2qi store.
> +proc check_effective_target_vect_slp_v8qi_store { } {
> +    set pattern {add new stmt: MEM <vector\(8\) char>}
> +    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
> +}
> +
> +# Return the true if target support vectorization of v4qi store.
> +proc check_effective_target_vect_slp_v16qi_store { } {
> +    set pattern {add new stmt: MEM <vector\(16\) char>}
> +    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
> +}
> +
> +# Return the true if target support vectorization of v2hi store.
> +proc check_effective_target_vect_slp_v2hi_store { } {
> +    set pattern {add new stmt: MEM <vector\(2\) short int>}
> +    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
> +}
> +
> +# Return the true if target support vectorization of v2hi store.
> +proc check_effective_target_vect_slp_v4hi_store { } {
> +    set pattern {add new stmt: MEM <vector\(4\) short int>}
> +    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
> +}
> +
>  # Return 1 if we can align stack data to the preferred vector alignment.
>  
>  proc check_effective_target_vect_align_stack_vars { } {
> 

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] Adjust testcase for O2 vectorization.
  2021-10-14 10:56                     ` Kewen.Lin
@ 2021-10-15  7:11                       ` Kewen.Lin
  2021-10-18  4:47                         ` Hongtao Liu
  0 siblings, 1 reply; 29+ messages in thread
From: Kewen.Lin @ 2021-10-15  7:11 UTC (permalink / raw)
  To: liuhongt; +Cc: gcc-patches, Martin Sebor

on 2021/10/14 下午6:56, Kewen.Lin via Gcc-patches wrote:
> Hi Hongtao,
> 
> on 2021/10/14 下午3:11, liuhongt wrote:
>> Hi Kewen:
>>   Cound you help to verify if this patch fix those regressions
>> for rs6000 port.
>>
> 
> The ppc64le run just finished, there are still some regresssions:
> 
> NA->XPASS: c-c++-common/Wstringop-overflow-2.c  -Wc++-compat   (test for warnings, line 194)
> NA->XPASS: c-c++-common/Wstringop-overflow-2.c  -Wc++-compat   (test for warnings, line 212)
> NA->XPASS: c-c++-common/Wstringop-overflow-2.c  -Wc++-compat   (test for warnings, line 296)
> NA->XPASS: c-c++-common/Wstringop-overflow-2.c  -Wc++-compat   (test for warnings, line 314)
> NA->FAIL: gcc.dg/Wstringop-overflow-21-novec.c (test for excess errors)
> NA->FAIL: gcc.dg/Wstringop-overflow-21-novec.c  (test for warnings, line 18)
> NA->FAIL: gcc.dg/Wstringop-overflow-21-novec.c  (test for warnings, line 29)
> NA->FAIL: gcc.dg/Wstringop-overflow-21-novec.c  (test for warnings, line 45)
> NA->FAIL: gcc.dg/Wstringop-overflow-21-novec.c  (test for warnings, line 55)
> NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 104)
> NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 137)
> NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 19)
> NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 39)
> NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 56)
> NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 70)
> NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c (test for excess errors)
> NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 116)
> NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 131)
> NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 146)
> NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 33)
> NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 50)
> NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 64)
> NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 78)
> NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 97)
> PASS->FAIL: c-c++-common/Wstringop-overflow-2.c  -std=gnu++14 (test for excess errors)
> NA->FAIL: c-c++-common/Wstringop-overflow-2.c  -std=gnu++14  (test for warnings, line 229)
> NA->FAIL: c-c++-common/Wstringop-overflow-2.c  -std=gnu++14  (test for warnings, line 230)
> NA->FAIL: c-c++-common/Wstringop-overflow-2.c  -std=gnu++14  (test for warnings, line 331)
> NA->FAIL: c-c++-common/Wstringop-overflow-2.c  -std=gnu++14  (test for warnings, line 332)
> // omitting -std=gnu++17, -std=gnu++2a, -std=gnu++98
> 
> I'll have a look and get back to you tomorrow.
> 

The failure c-c++-common/Wstringop-overflow-2.c is due to that the
current proc check_vect_slp_vnqihi_store_usage is made as "cache"
but it can vary for different input patterns.  For rs6000 the test
for v2qi fails, the cached test result makes v4qi check fail
unexpectedly (should pass).  I adjusted caching for the following users
check_effective_target_vect_slp_v*_store, also refactored a bit.
One trivial change is to add one new argument macro then we can just
compile the corresponding foo* function instead of all, hope it helps
to make the debugging outputs compact.

For the failure Wstringop-overflow-76-novec.c, there is one typo
comparing to the original Wstringop-overflow-76.c.  Guess it failed
on x86 too?  It would be surprising if it passes on x86.
As to the failure Wstringop-overflow-21-novec.c, I confirmed it's
just noise, patching typos caused this failure.

One new round ppc64le testing just finished with below diff and all
previous regressions are fixed without any new regressions.


diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
index d000b587a65..1132348c5f4 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
@@ -82,7 +82,7 @@ void max_d8_p (char *q, int i)
 struct A3_5
 {
   char a3[3];  // { dg-message "at offset 3 into destination object 'a3' of size 3" "pr??????" { xfail *-*-* } }
-  char a5[5];
+  char a5[5];  // { dg-message "at offset 5 into destination object 'a5' of size 5" "note" }
 };

 void max_A3_A5 (int i, struct A3_5 *pa3_5)
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 530c5769614..8736b908ec7 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -7584,12 +7584,13 @@ proc check_effective_target_vect_element_align_preferred { } {
 # Return zero if the desirable pattern isn't found.
 # It's used by Warray-bounds/Wstringop-overflow testcases which are
 # regressed by O2 vectorization, refer to PR102697/PR102462/PR102706
-proc check_vect_slp_vnqihi_store_usage { pattern } {
+proc check_vect_slp_vnqihi_store_usage { pattern macro } {
     global tool

-    return [check_cached_effective_target slp_vnqihi_store_usage {
-      set result [check_compile slp_vnqihi_store_usage assembly {
+    set result [check_compile slp_vnqihi_store_usage assembly {
 	  char a[16] __attribute__ ((aligned (16)));
+	  short b[4] __attribute__((aligned(8)));
+	  #ifdef TEST_V8QI
 	  void
 	  foo ()
 	  {
@@ -7602,7 +7603,7 @@ proc check_vect_slp_vnqihi_store_usage { pattern } {
 	      a[6] = 6;
 	      a[7] = 7;
 	  }
-
+	  #elif TEST_V16QI
 	  void
 	  foo1 ()
 	  {
@@ -7623,7 +7624,7 @@ proc check_vect_slp_vnqihi_store_usage { pattern } {
 	      a[14] = 14;
 	      a[15] = 15;
 	  }
-
+	  #elif TEST_V4QI
 	  void
 	  foo2 ()
 	  {
@@ -7632,22 +7633,21 @@ proc check_vect_slp_vnqihi_store_usage { pattern } {
 	      a[2] = 2;
 	      a[3] = 3;
 	  }
-
+	  #elif TEST_V2QI
 	  void
 	  foo3 ()
 	  {
 	      a[0] = 0;
 	      a[1] = 1;
 	  }
-
-	  short b[4] __attribute__((aligned(8)));
+	  #elif TEST_V2HI
 	  void
 	  foo4 ()
 	  {
 	      b[0] = 0;
 	      b[1] = 1;
 	  }
-
+	  #elif TEST_V4HI
 	  void
 	  foo5 ()
 	  {
@@ -7656,57 +7656,69 @@ proc check_vect_slp_vnqihi_store_usage { pattern } {
 	      b[2] = 2;
 	      b[3] = 3;
 	  }
+	  #endif

-      } "-O2 -fopt-info-all" ]
+      } "-O2 -fopt-info-all -D$macro" ]

       # Get compiler emitted messages and delete generated file.
       set lines [lindex $result 0]
       set output [lindex $result 1]
       remote_file build delete $output

-      # Capture the vectorized info of v2qi, set it to zero if not found.
-	if { ![regexp $pattern $lines whole val] } then {
-	  set val 0
+      # Check pattern exits in lines, set it to zero if not found.
+      if { [regexp $pattern $lines] } then {
+	 return 1
       }

-      return $val
-    }]
+      return 0
 }

 # Return the true if target support vectorization of v2qi store.
 proc check_effective_target_vect_slp_v2qi_store { } {
     set pattern {add new stmt: MEM <vector\(2\) char>}
-    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
+    set macro "TEST_V2QI"
+    return [check_cached_effective_target vect_slp_v2qi_store {
+	    expr [check_vect_slp_vnqihi_store_usage $pattern $macro] }]
 }

 # Return the true if target support vectorization of v4qi store.
 proc check_effective_target_vect_slp_v4qi_store { } {
     set pattern {add new stmt: MEM <vector\(4\) char>}
-    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
+    set macro "TEST_V4QI"
+    return [check_cached_effective_target vect_slp_v4qi_store {
+	    expr [check_vect_slp_vnqihi_store_usage $pattern $macro ] }]
 }

-# Return the true if target support vectorization of v2qi store.
+# Return the true if target support vectorization of v8qi store.
 proc check_effective_target_vect_slp_v8qi_store { } {
     set pattern {add new stmt: MEM <vector\(8\) char>}
-    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
+    set macro "TEST_V8QI"
+    return [check_cached_effective_target_vect_slp_v8qi_store {
+	    expr [check_vect_slp_vnqihi_store_usage $pattern $macro ] }]
 }

-# Return the true if target support vectorization of v4qi store.
+# Return the true if target support vectorization of v16qi store.
 proc check_effective_target_vect_slp_v16qi_store { } {
     set pattern {add new stmt: MEM <vector\(16\) char>}
-    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
+    set macro "TEST_V16QI"
+    return [check_cached_effective_target_vect_slp_v16qi_store {
+	    expr [check_vect_slp_vnqihi_store_usage $pattern $macro ] }]
 }

 # Return the true if target support vectorization of v2hi store.
 proc check_effective_target_vect_slp_v2hi_store { } {
     set pattern {add new stmt: MEM <vector\(2\) short int>}
-    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
+    set macro "TEST_V2HI"
+    return [check_cached_effective_target_vect_slp_v2hi_store {
+	    expr [check_vect_slp_vnqihi_store_usage $pattern $macro ] }]
 }

-# Return the true if target support vectorization of v2hi store.
+# Return the true if target support vectorization of v4hi store.
 proc check_effective_target_vect_slp_v4hi_store { } {
     set pattern {add new stmt: MEM <vector\(4\) short int>}
-    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
+    set macro "TEST_V4HI"
+    return [check_cached_effective_target_vect_slp_v4hi_store {
+	    expr [check_vect_slp_vnqihi_store_usage $pattern $macro ] }]
 }



BR,
Kewen

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] Adjust testcase for O2 vectorization.
  2021-10-14  7:11                   ` [PATCH] Adjust testcase for O2 vectorization liuhongt
  2021-10-14  7:52                     ` Bernhard Reutner-Fischer
  2021-10-14 10:56                     ` Kewen.Lin
@ 2021-10-15 15:37                     ` Martin Sebor
  2021-10-18  4:38                       ` Hongtao Liu
  2 siblings, 1 reply; 29+ messages in thread
From: Martin Sebor @ 2021-10-15 15:37 UTC (permalink / raw)
  To: liuhongt, gcc-patches

On 10/14/21 1:11 AM, liuhongt wrote:
> Hi Kewen:
>    Cound you help to verify if this patch fix those regressions
> for rs6000 port.
> 
> As discussed in [1], this patch add xfail/target selector to those
> testcases, also make a copy of them so that they can be tested w/o
> vectorization.

Just to make sure I understand what's happening with the tests:
the new -N-novec.c tests consist of just the casses xfailed due
to vectorizartion in the corresponding -N.c tests?  Or are there
some other differences (e.g., new cases in them, etc.)?  I'd
hope to eventually remove the -novec.c tests once all warnings
behave as expected with vectorization as without it (maybe
keeping just one case both ways as a sanity check).

For the target-supports selectors, I confess I don't know enough
about vectorization to find their names quite intuitive enough
to know when to use each.  For instance, for vect_slp_v4qi_store:

+# Return the true if target support vectorization of v4qi store.
+proc check_effective_target_vect_slp_v4qi_store { } {
+    set pattern {add new stmt: MEM <vector\(4\) char>}
+    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
+}

When should this selector be used?  In cases involving 4-byte
char stores?  Only naturally aligned 4-bytes stores (i.e., on
a 4 byte boundary, as the check_vect_slp_vnqihi_store_usage
suggests?) Or 4-byte stores of any types (e.g., four chars
as well as two 16-bit shorts), etc.?

Hopefully once all the warnings handle vectorization we won't
need to use them, but until then it would be good to document
this in more detail in the .exp file.

Finally, thank you for adding comments to the xfailed tests
referencing the corresponding bugs!  Can you please mention
the PR in the comment in each of the new xfails?  Like so:

index 7d29b5f48c7..cb687c69324 100644
--- a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
+++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
@@ -189,8 +189,9 @@ void ga1__ (void)

    struct A1 a = { 1 };
    a.a[0] = 0;
+  // O2 vectorization regress Wstringop-overflow case (1), refer to 
pr102462.
    a.a[1] = 1;                    // { dg-warning 
"\\\[-Wstringop-overflow" }
-  a.a[2] = 2;                    // { dg-warning 
"\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  a.a[2] = 2;                    // { dg-warning 
"\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store } } }
            ^^^^^^^^
            PR in dg-warning comment.

This should make it easier to deal with the XFAILs once
the warnings have improved to handle vectorization.

Martin

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] Adjust testcase for O2 vectorization.
  2021-10-15 15:37                     ` Martin Sebor
@ 2021-10-18  4:38                       ` Hongtao Liu
  2021-10-18 15:11                         ` Martin Sebor
  0 siblings, 1 reply; 29+ messages in thread
From: Hongtao Liu @ 2021-10-18  4:38 UTC (permalink / raw)
  To: Martin Sebor; +Cc: liuhongt, GCC Patches, Kewen.Lin

On Fri, Oct 15, 2021 at 11:37 PM Martin Sebor <msebor@gmail.com> wrote:
>
> On 10/14/21 1:11 AM, liuhongt wrote:
> > Hi Kewen:
> >    Cound you help to verify if this patch fix those regressions
> > for rs6000 port.
> >
> > As discussed in [1], this patch add xfail/target selector to those
> > testcases, also make a copy of them so that they can be tested w/o
> > vectorization.
>
> Just to make sure I understand what's happening with the tests:
> the new -N-novec.c tests consist of just the casses xfailed due
> to vectorizartion in the corresponding -N.c tests?  Or are there
Wstringop-overflow-2-novec.c is the same as Wstringop-overflow-2.c
before O2 vectorization adjustment.
Do you want me to reduce them to only contain cases for new xfail/target?
> some other differences (e.g., new cases in them, etc.)?  I'd
> hope to eventually remove the -novec.c tests once all warnings
> behave as expected with vectorization as without it (maybe
> keeping just one case both ways as a sanity check).
>
> For the target-supports selectors, I confess I don't know enough
> about vectorization to find their names quite intuitive enough
> to know when to use each.  For instance, for vect_slp_v4qi_store:
It's 4-byte char stores with address being 4-bytes aligned.
.i.e.

>
> +# Return the true if target support vectorization of v4qi store.
> +proc check_effective_target_vect_slp_v4qi_store { } {
> +    set pattern {add new stmt: MEM <vector\(4\) char>}
> +    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
> +}
>
> When should this selector be used?  In cases involving 4-byte
> char stores?  Only naturally aligned 4-bytes stores (i.e., on
> a 4 byte boundary, as the check_vect_slp_vnqihi_store_usage
> suggests?) Or 4-byte stores of any types (e.g., four chars
> as well as two 16-bit shorts), etc.?
>
> Hopefully once all the warnings handle vectorization we won't
> need to use them, but until then it would be good to document
> this in more detail in the .exp file.
>
> Finally, thank you for adding comments to the xfailed tests
> referencing the corresponding bugs!  Can you please mention
> the PR in the comment in each of the new xfails?  Like so:
>
> index 7d29b5f48c7..cb687c69324 100644
> --- a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> +++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> @@ -189,8 +189,9 @@ void ga1__ (void)
>
>     struct A1 a = { 1 };
>     a.a[0] = 0;
> +  // O2 vectorization regress Wstringop-overflow case (1), refer to
> pr102462.
>     a.a[1] = 1;                    // { dg-warning
> "\\\[-Wstringop-overflow" }
> -  a.a[2] = 2;                    // { dg-warning
> "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  a.a[2] = 2;                    // { dg-warning
> "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store } } }
>             ^^^^^^^^
>             PR in dg-warning comment.
>
> This should make it easier to deal with the XFAILs once
> the warnings have improved to handle vectorization.
Will do.
>
> Martin



-- 
BR,
Hongtao

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] Adjust testcase for O2 vectorization.
  2021-10-15  7:11                       ` Kewen.Lin
@ 2021-10-18  4:47                         ` Hongtao Liu
  0 siblings, 0 replies; 29+ messages in thread
From: Hongtao Liu @ 2021-10-18  4:47 UTC (permalink / raw)
  To: Kewen.Lin; +Cc: liuhongt, GCC Patches

On Fri, Oct 15, 2021 at 3:11 PM Kewen.Lin via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> on 2021/10/14 下午6:56, Kewen.Lin via Gcc-patches wrote:
> > Hi Hongtao,
> >
> > on 2021/10/14 下午3:11, liuhongt wrote:
> >> Hi Kewen:
> >>   Cound you help to verify if this patch fix those regressions
> >> for rs6000 port.
> >>
> >
> > The ppc64le run just finished, there are still some regresssions:
> >
> > NA->XPASS: c-c++-common/Wstringop-overflow-2.c  -Wc++-compat   (test for warnings, line 194)
> > NA->XPASS: c-c++-common/Wstringop-overflow-2.c  -Wc++-compat   (test for warnings, line 212)
> > NA->XPASS: c-c++-common/Wstringop-overflow-2.c  -Wc++-compat   (test for warnings, line 296)
> > NA->XPASS: c-c++-common/Wstringop-overflow-2.c  -Wc++-compat   (test for warnings, line 314)
> > NA->FAIL: gcc.dg/Wstringop-overflow-21-novec.c (test for excess errors)
> > NA->FAIL: gcc.dg/Wstringop-overflow-21-novec.c  (test for warnings, line 18)
> > NA->FAIL: gcc.dg/Wstringop-overflow-21-novec.c  (test for warnings, line 29)
> > NA->FAIL: gcc.dg/Wstringop-overflow-21-novec.c  (test for warnings, line 45)
> > NA->FAIL: gcc.dg/Wstringop-overflow-21-novec.c  (test for warnings, line 55)
> > NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 104)
> > NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 137)
> > NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 19)
> > NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 39)
> > NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 56)
> > NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c note (test for warnings, line 70)
> > NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c (test for excess errors)
> > NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 116)
> > NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 131)
> > NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 146)
> > NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 33)
> > NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 50)
> > NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 64)
> > NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 78)
> > NA->FAIL: gcc.dg/Wstringop-overflow-76-novec.c  (test for warnings, line 97)
> > PASS->FAIL: c-c++-common/Wstringop-overflow-2.c  -std=gnu++14 (test for excess errors)
> > NA->FAIL: c-c++-common/Wstringop-overflow-2.c  -std=gnu++14  (test for warnings, line 229)
> > NA->FAIL: c-c++-common/Wstringop-overflow-2.c  -std=gnu++14  (test for warnings, line 230)
> > NA->FAIL: c-c++-common/Wstringop-overflow-2.c  -std=gnu++14  (test for warnings, line 331)
> > NA->FAIL: c-c++-common/Wstringop-overflow-2.c  -std=gnu++14  (test for warnings, line 332)
> > // omitting -std=gnu++17, -std=gnu++2a, -std=gnu++98
> >
> > I'll have a look and get back to you tomorrow.
> >
>
> The failure c-c++-common/Wstringop-overflow-2.c is due to that the
> current proc check_vect_slp_vnqihi_store_usage is made as "cache"
> but it can vary for different input patterns.  For rs6000 the test
> for v2qi fails, the cached test result makes v4qi check fail
> unexpectedly (should pass).  I adjusted caching for the following users
> check_effective_target_vect_slp_v*_store, also refactored a bit.
> One trivial change is to add one new argument macro then we can just
> compile the corresponding foo* function instead of all, hope it helps
> to make the debugging outputs compact.
>
> For the failure Wstringop-overflow-76-novec.c, there is one typo
> comparing to the original Wstringop-overflow-76.c.  Guess it failed
> on x86 too?  It would be surprising if it passes on x86.
> As to the failure Wstringop-overflow-21-novec.c, I confirmed it's
> just noise, patching typos caused this failure.
Thanks for the explanation for  those failures and the typo, i'll
adjust the patch.
>
> One new round ppc64le testing just finished with below diff and all
> previous regressions are fixed without any new regressions.
>
>
> diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> index d000b587a65..1132348c5f4 100644
> --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> @@ -82,7 +82,7 @@ void max_d8_p (char *q, int i)
>  struct A3_5
>  {
>    char a3[3];  // { dg-message "at offset 3 into destination object 'a3' of size 3" "pr??????" { xfail *-*-* } }
> -  char a5[5];
> +  char a5[5];  // { dg-message "at offset 5 into destination object 'a5' of size 5" "note" }
>  };
>
>  void max_A3_A5 (int i, struct A3_5 *pa3_5)
> diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
> index 530c5769614..8736b908ec7 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -7584,12 +7584,13 @@ proc check_effective_target_vect_element_align_preferred { } {
>  # Return zero if the desirable pattern isn't found.
>  # It's used by Warray-bounds/Wstringop-overflow testcases which are
>  # regressed by O2 vectorization, refer to PR102697/PR102462/PR102706
> -proc check_vect_slp_vnqihi_store_usage { pattern } {
> +proc check_vect_slp_vnqihi_store_usage { pattern macro } {
>      global tool
>
> -    return [check_cached_effective_target slp_vnqihi_store_usage {
> -      set result [check_compile slp_vnqihi_store_usage assembly {
> +    set result [check_compile slp_vnqihi_store_usage assembly {
>           char a[16] __attribute__ ((aligned (16)));
> +         short b[4] __attribute__((aligned(8)));
> +         #ifdef TEST_V8QI
>           void
>           foo ()
>           {
> @@ -7602,7 +7603,7 @@ proc check_vect_slp_vnqihi_store_usage { pattern } {
>               a[6] = 6;
>               a[7] = 7;
>           }
> -
> +         #elif TEST_V16QI
>           void
>           foo1 ()
>           {
> @@ -7623,7 +7624,7 @@ proc check_vect_slp_vnqihi_store_usage { pattern } {
>               a[14] = 14;
>               a[15] = 15;
>           }
> -
> +         #elif TEST_V4QI
>           void
>           foo2 ()
>           {
> @@ -7632,22 +7633,21 @@ proc check_vect_slp_vnqihi_store_usage { pattern } {
>               a[2] = 2;
>               a[3] = 3;
>           }
> -
> +         #elif TEST_V2QI
>           void
>           foo3 ()
>           {
>               a[0] = 0;
>               a[1] = 1;
>           }
> -
> -         short b[4] __attribute__((aligned(8)));
> +         #elif TEST_V2HI
>           void
>           foo4 ()
>           {
>               b[0] = 0;
>               b[1] = 1;
>           }
> -
> +         #elif TEST_V4HI
>           void
>           foo5 ()
>           {
> @@ -7656,57 +7656,69 @@ proc check_vect_slp_vnqihi_store_usage { pattern } {
>               b[2] = 2;
>               b[3] = 3;
>           }
> +         #endif
>
> -      } "-O2 -fopt-info-all" ]
> +      } "-O2 -fopt-info-all -D$macro" ]
>
>        # Get compiler emitted messages and delete generated file.
>        set lines [lindex $result 0]
>        set output [lindex $result 1]
>        remote_file build delete $output
>
> -      # Capture the vectorized info of v2qi, set it to zero if not found.
> -       if { ![regexp $pattern $lines whole val] } then {
> -         set val 0
> +      # Check pattern exits in lines, set it to zero if not found.
> +      if { [regexp $pattern $lines] } then {
> +        return 1
>        }
>
> -      return $val
> -    }]
> +      return 0
>  }
>
>  # Return the true if target support vectorization of v2qi store.
>  proc check_effective_target_vect_slp_v2qi_store { } {
>      set pattern {add new stmt: MEM <vector\(2\) char>}
> -    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
> +    set macro "TEST_V2QI"
> +    return [check_cached_effective_target vect_slp_v2qi_store {
> +           expr [check_vect_slp_vnqihi_store_usage $pattern $macro] }]
>  }
>
>  # Return the true if target support vectorization of v4qi store.
>  proc check_effective_target_vect_slp_v4qi_store { } {
>      set pattern {add new stmt: MEM <vector\(4\) char>}
> -    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
> +    set macro "TEST_V4QI"
> +    return [check_cached_effective_target vect_slp_v4qi_store {
> +           expr [check_vect_slp_vnqihi_store_usage $pattern $macro ] }]
>  }
>
> -# Return the true if target support vectorization of v2qi store.
> +# Return the true if target support vectorization of v8qi store.
>  proc check_effective_target_vect_slp_v8qi_store { } {
>      set pattern {add new stmt: MEM <vector\(8\) char>}
> -    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
> +    set macro "TEST_V8QI"
> +    return [check_cached_effective_target_vect_slp_v8qi_store {
> +           expr [check_vect_slp_vnqihi_store_usage $pattern $macro ] }]
>  }
>
> -# Return the true if target support vectorization of v4qi store.
> +# Return the true if target support vectorization of v16qi store.
>  proc check_effective_target_vect_slp_v16qi_store { } {
>      set pattern {add new stmt: MEM <vector\(16\) char>}
> -    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
> +    set macro "TEST_V16QI"
> +    return [check_cached_effective_target_vect_slp_v16qi_store {
> +           expr [check_vect_slp_vnqihi_store_usage $pattern $macro ] }]
>  }
>
>  # Return the true if target support vectorization of v2hi store.
>  proc check_effective_target_vect_slp_v2hi_store { } {
>      set pattern {add new stmt: MEM <vector\(2\) short int>}
> -    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
> +    set macro "TEST_V2HI"
> +    return [check_cached_effective_target_vect_slp_v2hi_store {
> +           expr [check_vect_slp_vnqihi_store_usage $pattern $macro ] }]
>  }
>
> -# Return the true if target support vectorization of v2hi store.
> +# Return the true if target support vectorization of v4hi store.
>  proc check_effective_target_vect_slp_v4hi_store { } {
>      set pattern {add new stmt: MEM <vector\(4\) short int>}
> -    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
> +    set macro "TEST_V4HI"
> +    return [check_cached_effective_target_vect_slp_v4hi_store {
> +           expr [check_vect_slp_vnqihi_store_usage $pattern $macro ] }]
>  }
>
>
>
> BR,
> Kewen



-- 
BR,
Hongtao

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] Adjust testcase for O2 vectorization.
  2021-10-18  4:38                       ` Hongtao Liu
@ 2021-10-18 15:11                         ` Martin Sebor
  2021-10-19  9:03                           ` liuhongt
  0 siblings, 1 reply; 29+ messages in thread
From: Martin Sebor @ 2021-10-18 15:11 UTC (permalink / raw)
  To: Hongtao Liu; +Cc: liuhongt, GCC Patches, Kewen.Lin

On 10/17/21 10:38 PM, Hongtao Liu wrote:
> On Fri, Oct 15, 2021 at 11:37 PM Martin Sebor <msebor@gmail.com> wrote:
>>
>> On 10/14/21 1:11 AM, liuhongt wrote:
>>> Hi Kewen:
>>>     Cound you help to verify if this patch fix those regressions
>>> for rs6000 port.
>>>
>>> As discussed in [1], this patch add xfail/target selector to those
>>> testcases, also make a copy of them so that they can be tested w/o
>>> vectorization.
>>
>> Just to make sure I understand what's happening with the tests:
>> the new -N-novec.c tests consist of just the casses xfailed due
>> to vectorizartion in the corresponding -N.c tests?  Or are there
> Wstringop-overflow-2-novec.c is the same as Wstringop-overflow-2.c
> before O2 vectorization adjustment.
> Do you want me to reduce them to only contain cases for new xfail/target?

That would be helpful, thank you.  Are the others also full
copies? (If yes, then copying just the failing cases into
the new tests would be good as well.)

>> some other differences (e.g., new cases in them, etc.)?  I'd
>> hope to eventually remove the -novec.c tests once all warnings
>> behave as expected with vectorization as without it (maybe
>> keeping just one case both ways as a sanity check).
>>
>> For the target-supports selectors, I confess I don't know enough
>> about vectorization to find their names quite intuitive enough
>> to know when to use each.  For instance, for vect_slp_v4qi_store:
> It's 4-byte char stores with address being 4-bytes aligned.
> .i.e.
> 
>>
>> +# Return the true if target support vectorization of v4qi store.
>> +proc check_effective_target_vect_slp_v4qi_store { } {
>> +    set pattern {add new stmt: MEM <vector\(4\) char>}
>> +    return [expr { [check_vect_slp_vnqihi_store_usage $pattern ] != 0 }]
>> +}
>>
>> When should this selector be used?  In cases involving 4-byte
>> char stores?  Only naturally aligned 4-bytes stores (i.e., on
>> a 4 byte boundary, as the check_vect_slp_vnqihi_store_usage
>> suggests?) Or 4-byte stores of any types (e.g., four chars
>> as well as two 16-bit shorts), etc.?
>>
>> Hopefully once all the warnings handle vectorization we won't
>> need to use them, but until then it would be good to document
>> this in more detail in the .exp file.
>>
>> Finally, thank you for adding comments to the xfailed tests
>> referencing the corresponding bugs!  Can you please mention
>> the PR in the comment in each of the new xfails?  Like so:
>>
>> index 7d29b5f48c7..cb687c69324 100644
>> --- a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
>> +++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
>> @@ -189,8 +189,9 @@ void ga1__ (void)
>>
>>      struct A1 a = { 1 };
>>      a.a[0] = 0;
>> +  // O2 vectorization regress Wstringop-overflow case (1), refer to
>> pr102462.
>>      a.a[1] = 1;                    // { dg-warning
>> "\\\[-Wstringop-overflow" }
>> -  a.a[2] = 2;                    // { dg-warning
>> "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
>> +  a.a[2] = 2;                    // { dg-warning
>> "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store } } }
>>              ^^^^^^^^
>>              PR in dg-warning comment.
>>
>> This should make it easier to deal with the XFAILs once
>> the warnings have improved to handle vectorization.
> Will do.

Great, thank you!

Martin

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH] Adjust testcase for O2 vectorization.
  2021-10-18 15:11                         ` Martin Sebor
@ 2021-10-19  9:03                           ` liuhongt
  2021-10-20 11:34                             ` Christophe Lyon
  0 siblings, 1 reply; 29+ messages in thread
From: liuhongt @ 2021-10-19  9:03 UTC (permalink / raw)
  To: gcc-patches

updated patch:
  1. Add documents in doc/sourcebuild.texi (Effective-Target Keywords).
  2. Reduce -novec.c testcases to contain only new failed parted which
is caused by O2 vectorization.
  3. Add PR in dg-warning comment.

As discussed in [1], this patch add xfail/target selector to those
testcases, also make a copy of them so that they can be tested w/o
vectorization.

Newly added xfail/target selectors are used to check the vectorization
capability of continuous byte/double bytes storage, these scenarios
are exactly the part of the testcases that regressed after O2
vectorization.

[1] https://gcc.gnu.org/pipermail/gcc-patches/2021-October/581456.html.

gcc/ChangeLog

	* doc/sourcebuild.texi (Effective-Target Keywords): Document
	vect_slp_v2qi_store, vect_slp_v4qi_store, vect_slp_v8qi_store,
	vect_slp_v16qi_store, vect_slp_v2hi_store,
	vect_slp_v4hi_store, vect_slp_v2si_store, vect_slp_v4si_store.

gcc/testsuite/ChangeLog

	PR middle-end/102722
	PR middle-end/102697
	PR middle-end/102462
	PR middle-end/102706
	PR middle-end/102744
	* c-c++-common/Wstringop-overflow-2.c: Adjust testcase with new
	xfail/target selector.
	* gcc.dg/Warray-bounds-51.c: Ditto.
	* gcc.dg/Warray-parameter-3.c: Ditto.
	* gcc.dg/Wstringop-overflow-14.c: Ditto.
	* gcc.dg/Wstringop-overflow-21.c: Ditto.
	* gcc.dg/Wstringop-overflow-68.c: Ditto.
	* gcc.dg/Wstringop-overflow-76.c: Ditto.
	* gcc.dg/Warray-bounds-48.c: Ditto.
	* gcc.dg/Wzero-length-array-bounds-2.c: Ditto.
	* lib/target-supports.exp (check_vect_slp_aligned_store_usage):
	New function.
	(check_effective_target_vect_slp_v2qi_store): Ditto.
	(check_effective_target_vect_slp_v4qi_store): Ditto.
	(check_effective_target_vect_slp_v8qi_store): Ditto.
	(check_effective_target_vect_slp_v16qi_store): Ditto.
	(check_effective_target_vect_slp_v2hi_store): Ditto.
	(check_effective_target_vect_slp_v4hi_store): Ditto.
	(check_effective_target_vect_slp_v2si_store): Ditto.
	(check_effective_target_vect_slp_v4si_store): Ditto.
	* c-c++-common/Wstringop-overflow-2-novec.c: New test.
	* gcc.dg/Warray-bounds-51-novec.c: New test.
	* gcc.dg/Warray-bounds-48-novec.c: New test.
	* gcc.dg/Warray-parameter-3-novec.c: New test.
	* gcc.dg/Wstringop-overflow-14-novec.c: New test.
	* gcc.dg/Wstringop-overflow-21-novec.c: New test.
	* gcc.dg/Wstringop-overflow-76-novec.c: New test.
	* gcc.dg/Wzero-length-array-bounds-2-novec.c: New test.
---
 gcc/doc/sourcebuild.texi                      |  32 ++
 .../c-c++-common/Wstringop-overflow-2-novec.c | 126 ++++++
 .../c-c++-common/Wstringop-overflow-2.c       |  20 +-
 gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c | 364 ++++++++++++++++++
 gcc/testsuite/gcc.dg/Warray-bounds-48.c       |   4 +-
 gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c |  21 +
 gcc/testsuite/gcc.dg/Warray-bounds-51.c       |   2 +-
 .../gcc.dg/Warray-parameter-3-novec.c         |  16 +
 gcc/testsuite/gcc.dg/Warray-parameter-3.c     |   2 +-
 .../gcc.dg/Wstringop-overflow-14-novec.c      |  16 +
 gcc/testsuite/gcc.dg/Wstringop-overflow-14.c  |   4 +-
 .../gcc.dg/Wstringop-overflow-21-novec.c      |  34 ++
 gcc/testsuite/gcc.dg/Wstringop-overflow-21.c  |   8 +-
 gcc/testsuite/gcc.dg/Wstringop-overflow-68.c  |  17 +-
 .../gcc.dg/Wstringop-overflow-76-novec.c      |  88 +++++
 gcc/testsuite/gcc.dg/Wstringop-overflow-76.c  |  18 +-
 .../Wzero-length-array-bounds-2-novec.c       |  45 +++
 .../gcc.dg/Wzero-length-array-bounds-2.c      |   2 +-
 gcc/testsuite/lib/target-supports.exp         | 182 +++++++++
 19 files changed, 967 insertions(+), 34 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
 create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
 create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
 create mode 100644 gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
 create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
 create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
 create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
 create mode 100644 gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c

diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index b1fffd5e90f..6a165767630 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -1845,6 +1845,38 @@ Target supports loop vectorization with partial vectors and
 @item vect_partial_vectors
 Target supports loop vectorization with partial vectors and
 @code{vect-partial-vector-usage} is nonzero.
+
+@item vect_slp_v2qi_store
+Target supports vectorization of 2-byte char stores with 2-byte aligned
+address at plain @option{-O2}.
+
+@item vect_slp_v4qi_store
+Target supports vectorization of 4-byte char stores with 4-byte aligned
+address at plain @option{-O2}.
+
+@item vect_slp_v8qi_store
+Target supports vectorization of 8-byte char stores with 8-byte aligned
+address at plain @option{-O2}.
+
+@item vect_slp_v16qi_store
+Target supports vectorization of 16-byte char stores with 16-byte aligned
+address at plain @option{-O2}.
+
+@item vect_slp_v2hi_store
+Target supports vectorization of 4-byte short stores with 4-byte aligned
+address at plain @option{-O2}.
+
+@item vect_slp_v4hi_store
+Target supports vectorization of 8-byte short stores with 8-byte aligned
+address at plain @option{-O2}.
+
+@item vect_slp_v2si_store
+Target supports vectorization of 8-byte int stores with 8-byte aligned
+address at plain @option{-O2}.
+
+@item vect_slp_v4si_store
+Target supports vectorization of 16-byte int stores with 16-byte aligned
+address at plain @option{-O2}.
 @end table
 
 @subsubsection Thread Local Storage attributes
diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c b/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
new file mode 100644
index 00000000000..3c34ad35a5d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
@@ -0,0 +1,126 @@
+/* PR middle-end/91458 - inconsistent warning for writing past the end
+   of an array member
+   { dg-do compile }
+   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds -fno-ipa-icf" } */
+
+void sink (void*);
+
+// Exercise trailing one-element array members.
+
+struct A1
+{
+  char n;
+  char a[1];                    // { dg-message "destination object" "note" }
+};
+
+// Verify warning for access to a definition with an initializer that doesn't
+// initialize the one-element array member.
+struct A1 a1__ = { 0 };
+
+void ga1__ (void)
+{
+  a1__.a[0] = 0;
+  a1__.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a1__.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a = { 1 };
+  a.a[0] = 0;
+  a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the one-element array member to empty.
+struct A1 a1_0 = { 0, { } };
+
+void ga1_0_ (void)
+{
+  a1_0.a[0] = 0;
+  a1_0.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
+  a1_0.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a = { 1, { } };
+  a.a[0] = 0;
+  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the one-element array member.
+struct A1 a1_1 = { 0, { 1 } };
+
+void ga1_1 (void)
+{
+  a1_1.a[0] = 0;
+  a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
+  a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a = { 0, { 1 } };
+  a.a[0] = 0;
+  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Exercise interior one-element array members (verify they're not
+// treated as trailing.
+
+struct A1i
+{
+  char n;
+  char a[1];                    // { dg-message "destination object" }
+  char x;
+};
+
+// Verify warning for access to a definition with an initializer that doesn't
+// initialize the one-element array member.
+struct A1i a1i__ = { 0 };
+
+void ga1i__ (void)
+{
+  a1i__.a[0] = 0;
+  a1i__.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
+  a1i__.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1i a = { 0 };
+  a.a[0] = 0;
+  a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the one-element array member to empty.
+struct A1 a1i_0 = { 0, { } };
+
+void ga1i_0_ (void)
+{
+  a1i_0.a[0] = 0;
+  a1i_0.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow" }
+  a1i_0.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a = { 0, { } };
+  a.a[0] = 0;
+  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the one-element array member.
+struct A1 a1i_1 = { 0, { 1 } };
+
+void ga1i_1 (void)
+{
+  a1i_1.a[0] = 0;
+  a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow" }
+  a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a = { 0, { 1 } };
+  a.a[0] = 1;
+  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
index 7d29b5f48c7..ca38bda73f5 100644
--- a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
+++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
@@ -190,7 +190,7 @@ void ga1__ (void)
   struct A1 a = { 1 };
   a.a[0] = 0;
   a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
-  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store } } }
   sink (&a);
 }
 
@@ -207,7 +207,7 @@ void ga1_0_ (void)
   struct A1 a = { 1, { } };
   a.a[0] = 0;
   a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
-  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store } } }
   sink (&a);
 }
 
@@ -221,10 +221,10 @@ void ga1_1 (void)
   a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
   a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
 
-  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v4qi_store } } }
   a.a[0] = 0;
-  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
-  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store } } }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { vect_slp_v4qi_store } } }
   sink (&a);
 }
 
@@ -289,7 +289,7 @@ void ga1i__ (void)
   struct A1i a = { 0 };
   a.a[0] = 0;
   a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
-  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store } } }
   sink (&a);
 }
 
@@ -306,7 +306,7 @@ void ga1i_0_ (void)
   struct A1 a = { 0, { } };
   a.a[0] = 0;
   a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
-  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store } } }
   sink (&a);
 }
 
@@ -320,10 +320,10 @@ void ga1i_1 (void)
   a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow" }
   a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow" }
 
-  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow" "pr102462" { target { vect_slp_v4qi_store } } }
   a.a[0] = 1;
-  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
-  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v4qi_store } } }
+  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v4qi_store } } }
   sink (&a);
 }
 
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
new file mode 100644
index 00000000000..da179a2c0f5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
@@ -0,0 +1,364 @@
+/* PR middle-end/91647 - missing -Warray-bounds accessing a zero-length array
+   of a declared object
+   { dg-do "compile" }
+   { dg-options "-O2 -Wall -fno-tree-vectorize" }
+   { dg-require-effective-target alloca } */
+
+typedef __INT16_TYPE__ int16_t;
+typedef __INT32_TYPE__ int32_t;
+
+void sink (void*);
+
+/* Exercise a true flexible member.  */
+
+struct AX
+{
+  int32_t n;
+  int16_t ax[];     // { dg-message "while referencing 'ax'" "member" }
+};
+
+static void warn_ax_local (struct AX *p)
+{
+  p->ax[0] = 0;     // { dg-warning "\\\[-Warray-bounds" }
+  p->ax[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void nowarn_ax_extern (struct AX *p)
+{
+  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
+}
+
+static void warn_ax_local_buf (struct AX *p)
+{
+  p->ax[0] = 4; p->ax[1] = 5;
+
+  p->ax[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
+  p->ax[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
+  p->ax[4] = 8;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_ax_extern_buf (struct AX *p)
+{
+  p->ax[0] = 9; p->ax[1] = 10; p->ax[2] = 11;
+
+  p->ax[3] = 12;    // { dg-warning "\\\[-Warray-bounds" }
+  p->ax[4] = 13;    // { dg-warning "\\\[-Warray-bounds" }
+  p->ax[5] = 14;    // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void nowarn_ax_extern_bufx (struct AX *p)
+{
+  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
+}
+
+static void nowarn_ax_ref (struct AX *p)
+{
+  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
+}
+
+void test_ax (struct AX *p, unsigned n)
+{
+  {
+    struct AX sax;  // { dg-message "defined here" "struct definition" }
+    warn_ax_local (&sax);
+    sink (&sax);
+  }
+
+  {
+    extern
+      struct AX xsax;
+    nowarn_ax_extern (&xsax);
+    sink (&xsax);
+  }
+
+  {
+    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
+    char ax_buf_p2[sizeof (struct AX) + 2 * sizeof (int16_t)];
+    warn_ax_local_buf ((struct AX*) ax_buf_p2);
+    sink (ax_buf_p2);
+  }
+
+  {
+    /* Verify out-of-bounds access to the extern BUF with a known
+       bound is diagnosed.  */
+    extern char ax_buf_p3[sizeof (struct AX) + 3 * sizeof (int16_t)];
+    warn_ax_extern_buf ((struct AX*) ax_buf_p3);
+    sink (ax_buf_p3);
+  }
+
+  {
+    /* Verify that accesses to BUFX with an unknown bound are not
+       diagnosed.  */
+    extern char bufx[];
+    nowarn_ax_extern_bufx ((struct AX*) bufx);
+    sink (bufx);
+  }
+
+  {
+    /* Verify that accesses to BUFN with a runtime bound are not
+       diagnosed.  */
+    char bufn[n];
+    nowarn_ax_extern_bufx ((struct AX*) bufn);
+    sink (bufn);
+  }
+
+  nowarn_ax_ref (p);
+}
+
+
+/* Exercise a zero-length trailing member array.  It's the same as above
+   except that extern declarations with no definitions are considered to
+   have zero elements (they can't be initialized to have any).  */
+
+struct A0
+{
+  int32_t n;
+  int16_t a0[0];    // { dg-message "while referencing 'a0'" "member" }
+};
+
+static void warn_a0_local (struct A0 *p)
+{
+  p->a0[0] = 0;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a0[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a0_extern (struct A0 *p)
+{
+  p->a0[0] = 2;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a0[1] = 3;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a0_local_buf (struct A0 *p)
+{
+  p->a0[0] = 4; p->a0[1] = 5;
+
+  p->a0[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a0[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a0[4] = 8;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a0_extern_buf (struct A0 *p)
+{
+  p->a0[0] = 9; p->a0[1] = 10; p->a0[2] = 11;
+
+  p->a0[3] = 12;    // { dg-warning "\\\[-Warray-bounds" }
+  p->a0[4] = 13;    // { dg-warning "\\\[-Warray-bounds" }
+  p->a0[5] = 14;    // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void nowarn_a0_extern_bufx (struct A0 *p)
+{
+  p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
+}
+
+static void nowarn_a0_ref (struct A0 *p)
+{
+  p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
+}
+
+void test_a0 (struct A0 *p, unsigned n)
+{
+  {
+    struct A0 sa0;  // { dg-message "defined here" "struct definition" }
+    warn_a0_local (&sa0);
+    sink (&sa0);
+  }
+
+  {
+    extern
+      struct A0 xsa0;  // { dg-message "defined here" "struct definition" }
+    warn_a0_extern (&xsa0);
+    sink (&xsa0);
+  }
+
+  {
+    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
+    char a0_buf_p2[sizeof (struct A0) + 2 * sizeof (int16_t)];
+    warn_a0_local_buf ((struct A0*) a0_buf_p2);
+    sink (a0_buf_p2);
+  }
+
+  {
+    /* Verify out-of-bounds access to the extern BUF with a known
+       bound is diagnosed.  */
+    extern char a0_buf_p3[sizeof (struct A0) + 3 * sizeof (int16_t)];
+    warn_a0_extern_buf ((struct A0*) a0_buf_p3);
+    sink (a0_buf_p3);
+  }
+
+  {
+    /* Verify that accesses to BUFX with an unknown bound are not
+       diagnosed.  */
+    extern char bufx[];
+    nowarn_a0_extern_bufx ((struct A0*) bufx);
+    sink (bufx);
+  }
+
+  {
+    /* Verify that accesses to BUFN with a runtime bound are not
+       diagnosed.  */
+    char bufn[n];
+    nowarn_a0_extern_bufx ((struct A0*) bufn);
+    sink (bufn);
+  }
+
+  nowarn_a0_ref (p);
+}
+
+
+/* Exercise a one-element trailing member array.  It's the same as above
+   except that it has exactly one element.  */
+
+struct A1
+{
+  int32_t n;
+  int16_t a1[1];    // { dg-message "while referencing 'a1'" }
+};
+
+static void warn_a1_local_noinit (struct A1 *p)
+{
+  p->a1[0] = 0;
+  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a1_extern (struct A1 *p)
+{
+  p->a1[0] = 0;
+  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a1_init (struct A1 *p)
+{
+  p->a1[0] = 0;
+  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a1_local_buf (struct A1 *p)
+{
+  p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3;
+
+  p->a1[4] = 4;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a1_extern_buf (struct A1 *p)
+{
+  p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3; p->a1[4] = 4;
+
+  p->a1[5] = 5;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void nowarn_a1_extern_bufx (struct A1 *p)
+{
+  p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
+}
+
+static void nowarn_a1_ref (struct A1 *p)
+{
+  p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
+}
+
+void test_a1 (struct A1 *p, unsigned n)
+{
+  {
+    struct A1 a1;
+    warn_a1_local_noinit (&a1);
+    sink (&a1);
+  }
+
+  {
+    extern struct A1 a1x;
+    warn_a1_extern (&a1x);
+    sink (&a1x);
+}
+  {
+    struct A1 a1 = { 0, { 1 } };
+    warn_a1_init (&a1);
+    sink (&a1);
+  }
+
+  {
+    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
+    char buf_p2[sizeof (struct A1) + 2 * sizeof (int16_t)];
+    warn_a1_local_buf ((struct A1*) buf_p2);
+    sink (buf_p2);
+  }
+
+  {
+    /* Verify out-of-bounds access to the extern BUF with a known
+       bound is diagnosed.  */
+    extern char a1_buf_p3[sizeof (struct A1) + 3 * sizeof (int16_t)];
+    warn_a1_extern_buf ((struct A1*) a1_buf_p3);
+    sink (a1_buf_p3);
+  }
+
+  {
+    /* Verify that accesses to BUFX with an unknown bound are not
+       diagnosed.  */
+    extern char bufx[];
+    nowarn_a1_extern_bufx ((struct A1*) bufx);
+    sink (bufx);
+  }
+
+  {
+    /* Verify that accesses to BUFN with a runtime bound are not
+       diagnosed.  */
+    char bufn[n];
+    nowarn_a1_extern_bufx ((struct A1*) bufn);
+    sink (bufn);
+  }
+
+  nowarn_a1_ref (p);
+}
+
+
+/* Exercise a two-element trailing member array.  It's treated
+   the same as an interior array member.  */
+
+struct A2
+{
+  int32_t n;
+  int16_t a2[2];    // { dg-message "while referencing 'a2'" }
+};
+
+static void warn_a2_noinit (struct A2 *p)
+{
+  p->a2[0] = 0; p->a2[1] = 1;
+
+  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a2_init (struct A2 *p)
+{
+  p->a2[0] = 0; p->a2[1] = 1;
+
+  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a2[9] = 9;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+static void warn_a2_ref (struct A2 *p)
+{
+  p->a2[0] = 0; p->a2[1] = 1;
+
+  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
+  p->a2[9] = 9;     // { dg-warning "\\\[-Warray-bounds" }
+}
+
+void test_a2 (struct A2 *p)
+{
+  {
+    struct A2 a2;
+    warn_a2_noinit (&a2);
+    sink (&a2);
+  }
+
+  {
+    struct A2 a2 = { 0, { 1, 2 } };
+    warn_a2_init (&a2);
+    sink (&a2);
+  }
+
+  warn_a2_ref (p);
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48.c b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
index 13373d1e99e..19b7634c063 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-48.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
@@ -30,7 +30,7 @@ static void nowarn_ax_extern (struct AX *p)
 
 static void warn_ax_local_buf (struct AX *p)
 {
-  p->ax[0] = 4; p->ax[1] = 5;
+  p->ax[0] = 4; p->ax[1] = 5;  // { dg-warning "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v2hi_store &&  { ! vect_slp_v4hi_store } } } }
 
   p->ax[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
   p->ax[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
@@ -130,7 +130,7 @@ static void warn_a0_extern (struct A0 *p)
 
 static void warn_a0_local_buf (struct A0 *p)
 {
-  p->a0[0] = 4; p->a0[1] = 5;
+  p->a0[0] = 4; p->a0[1] = 5;  // { dg-warning "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v2hi_store && { ! vect_slp_v4hi_store } } } }
 
   p->a0[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
   p->a0[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c b/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
new file mode 100644
index 00000000000..ef8056d9b7f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
@@ -0,0 +1,21 @@
+/* PR middle-end/92333 - missing variable name referencing VLA in warnings
+   PR middle-end/82608 - missing -Warray-bounds on an out-of-bounds VLA index
+   { dg-do compile }
+   { dg-options "-O2 -Wall -fno-tree-vectorize" }  */
+
+void sink (void*);
+
+void test_struct_char_vla_location (void)
+{
+  unsigned nelts = 7;
+
+  struct {
+    char cvla[nelts]; // { dg-message "declared here|while referencing" }
+  } s;
+
+  s.cvla[0] = __LINE__;
+  s.cvla[nelts - 1] = 0;
+  s.cvla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
+
+  sink (&s);
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-51.c b/gcc/testsuite/gcc.dg/Warray-bounds-51.c
index de60d87ab95..8b589f38191 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-51.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-51.c
@@ -39,7 +39,7 @@ void test_struct_char_vla_location (void)
   } s;
 
   s.cvla[0] = __LINE__;
-  s.cvla[nelts - 1] = 0; // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  s.cvla[nelts - 1] = 0; // { dg-warning "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v2qi_store } } }
   s.cvla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
 
   sink (&s);
diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c b/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
new file mode 100644
index 00000000000..5089d555392
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
@@ -0,0 +1,16 @@
+/* PR c/50584 - No warning for passing small array to C99 static array
+   declarator
+   { dg-do compile }
+   { dg-options "-Wall -Warray-parameter=1" } */
+
+/* Also verify that -Warray-bounds doesn't trigger for ordinary array
+   parameters...  */
+#pragma GCC optimize ("2,no-tree-vectorize")
+
+/* ...but does for static arrays.  */
+__attribute__ ((noipa)) void
+gcas3 (char a[static 3])
+{
+  a[0] = 0; a[1] = 1; a[2] = 2;
+  a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3.c b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
index e8a269c85c6..b6ed8daf51c 100644
--- a/gcc/testsuite/gcc.dg/Warray-parameter-3.c
+++ b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
@@ -77,7 +77,7 @@ gia3 (int a[3])
 __attribute__ ((noipa)) void
 gcas3 (char a[static 3])
 {
-  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v4qi_store } } }
   a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
 }
 
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
new file mode 100644
index 00000000000..de39eaaeb95
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
@@ -0,0 +1,16 @@
+/* Test to verify that past-the-end multibyte writes via lvalues of wider
+   types than char are diagnosed.
+   { dg-do compile }
+   { dg-require-effective-target int32plus }
+   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds" }  */
+
+typedef __INT16_TYPE__  int16_t;
+
+char a4[4], a8[8], a16[16];
+
+void test_int16 (void)
+{
+  char *p = a4 + 1;
+  *(int16_t*)p = 0;
+  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a region of size 1" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
index 7683084e46e..c4a3f05d883 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
@@ -36,8 +36,8 @@ void test_memcpy_cond (int i)
 void test_int16 (void)
 {
   char *p = a4 + 1;
-  *(int16_t*)p = 0;    // { dg-warning "writing 4 bytes into a region of size 3" "" { target { i?86-*-* x86_64-*-* } } }
-  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a region of size 1" "" { xfail { i?86-*-* x86_64-*-* } } }
+  *(int16_t*)p = 0;    // { dg-warning "writing 4 bytes into a region of size 3" "pr102706" { target { vect_slp_v2hi_store } } }
+  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a region of size 1" "pr102706" { xfail { vect_slp_v2hi_store } } }
 }
 
 
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
new file mode 100644
index 00000000000..6f83548e902
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
@@ -0,0 +1,34 @@
+/* PR middle-end/92312 - bogus -Wstringop-overflow storing into a trailing
+   array backed by larger buffer
+   { dg-do compile }
+   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds" } */
+
+struct S0 { char a, b[0]; };
+
+void sink (void*);
+
+void test_store_zero_length (int i)
+{
+  char a[3];
+  struct S0 *p = (struct S0*)a;
+  p->a = 0;
+  p->b[0] = 0;
+  p->b[1] = 1;                      // { dg-bogus "\\\[-Wstringop-overflow" }
+  p->b[2] = 2;                      // { dg-warning "\\\[-Wstringop-overflow" }
+  p->b[i] = 2;
+  sink (p);
+}
+
+struct Sx { char a, b[]; };
+
+void test_store_flexarray (int i)
+{
+  char a[3];
+  struct Sx *p = (struct Sx*)a;
+  p->a = 0;
+  p->b[0] = 0;
+  p->b[1] = 1;                      // { dg-bogus "\\\[-Wstringop-overflow" }
+  p->b[2] = 1;                      // { dg-warning "\\\[-Wstringop-overflow" }
+  p->b[i] = 2;
+  sink (p);
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
index d88bde9c740..3fccfc9a798 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
@@ -23,10 +23,10 @@ void test_store_zero_length (int i)
 {
   char a[3];
   struct S0 *p = (struct S0*)a;
-  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v4qi_store } } }
   p->b[0] = 0;
   p->b[1] = 1;                      // { dg-bogus "\\\[-Wstringop-overflow" }
-  p->b[2] = 2;                      // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  p->b[2] = 2;                      // { dg-warning "\\\[-Wstringop-overflow" "pr102706" { xfail { vect_slp_v4qi_store } } }
   p->b[i] = 2;
   sink (p);
 }
@@ -50,10 +50,10 @@ void test_store_flexarray (int i)
 {
   char a[3];
   struct Sx *p = (struct Sx*)a;
-  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
+  p->a = 0;                         // { dg-warning "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v4qi_store } } }
   p->b[0] = 0;
   p->b[1] = 1;                      // { dg-bogus "\\\[-Wstringop-overflow" }
-  p->b[2] = 1;                      // { dg-warning "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
+  p->b[2] = 1;                      // { dg-warning "\\\[-Wstringop-overflow" "pr102706" { xfail { vect_slp_v4qi_store } } }
   p->b[i] = 2;
   sink (p);
 }
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
index 09df0004991..04e91afb8bc 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
@@ -58,11 +58,18 @@ void warn_comp_lit_zero (void)
 void warn_comp_lit (void)
 {
   *(AC2*)a1 = Ac2;      // { dg-warning "writing 2 bytes into a region of size 1" "pr101475" { xfail *-*-* } }
-  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 2" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
-  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 3" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
-  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 4" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
-  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 7" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
-  *(AC16*)a15 = Ac16;   // { dg-warning "writing 16 bytes into a region of size 15" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
+  // After vectorization, below codes are optimized to
+  // MEM <vector(4) char> [(char *)&a2] = { 0, 1, 2, 3 };
+  // MEM <vector(4) char> [(char *)&a3] = { 0, 1, 2, 3 };
+  // MEM <vector(8) char> [(char *)&a4] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+  // MEM <vector(8) char> [(char *)&a7] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+  // MEM <vector(16) char> [(char *)&a15] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+  // and warning should be expected, refer to PR102722.
+  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 2" "pr101475" { xfail { ! { vect_slp_v4qi_store } } } }
+  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of size 3" "pr101475" { xfail { ! { vect_slp_v4qi_store } } } }
+  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 4" "pr101475" { xfail { ! { vect_slp_v8qi_store } } } }
+  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of size 7" "pr101475" { xfail { ! { vect_slp_v8qi_store } } } }
+  *(AC16*)a15 = Ac16;   // { dg-warning "writing 16 bytes into a region of size 15" "pr101475" { xfail { ! { vect_slp_v16qi_store } } } }
 }
 
 void warn_aggr_decl (void)
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
new file mode 100644
index 00000000000..71c643b62fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
@@ -0,0 +1,88 @@
+/* Verify warnings and notes for MAX_EXPRs involving either pointers
+   to distinct objects or one to a known object and the other to
+   an unknown one.  Unlike for the same object, for unrelated objects
+   the expected warnings and notes are the same as for MIN_EXPR: when
+   the order of the objects in the address space cannot be determined
+   the larger of them is assumed to be used.  (This is different for
+   distinct struct members where the order is given.)
+   The relational expressions are strictly invalid but that should be
+   diagnosed by a separate warning.
+   { dg-do compile }
+   { dg-options "-O2 -Wno-array-bounds -fno-tree-vectorize" } */
+
+#define MAX(p, q) ((p) > (q) ? (p) : (q))
+
+/* Verify that even for MAX_EXPR and like for MIN_EXPR, the note points
+   to the larger of the two objects and mentions the offset into it
+   (although the offset might be better included in the warning).  */
+extern char a3[3];
+extern char a5[5];  // { dg-message "at offset 5 into destination object 'a5' of size 5" "note" }
+
+void max_a3_a5 (int i)
+{
+  char *p = a3 + i;
+  char *q = a5 + i;
+
+  /* The relational expression below is invalid and should be diagnosed
+     by its own warning independently of -Wstringop-overflow.  */
+  char *d = MAX (p, q);
+
+  d[2] = 0;
+  d[3] = 0;
+  d[4] = 0;
+  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
+}
+
+
+// Same as above but with the larger array as the first MAX_EXPR operand.
+extern char b4[4];
+extern char b6[6];  // { dg-message "at offset 6 into destination object 'b6' of size 6" "note" }
+
+void max_b6_b4 (int i)
+{
+  char *p = b6 + i;
+  char *q = b4 + i;
+  char *d = MAX (p, q);
+
+  d[3] = 0;
+  d[4] = 0;
+  d[5] = 0;
+  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
+}
+
+struct A3_5
+{
+  char a3[3];  // { dg-message "at offset 3 into destination object 'a3' of size 3" "pr??????" { xfail *-*-* } }
+  char a5[5];  // { dg-message "at offset 5 into destination object 'a5' of size 5" "note" }
+};
+
+void max_A3_A5 (int i, struct A3_5 *pa3_5)
+{
+  char *p = pa3_5->a3 + i;
+  char *q = pa3_5->a5 + i;
+
+  char *d = MAX (p, q);
+  d[2] = 0;
+  d[3] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "pr??????" { xfail *-*-* } }
+  d[4] = 0;
+  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
+}
+
+
+struct B4_B6
+{
+  char b4[4];
+  char b6[6];       // { dg-message "at offset 6 into destination object 'b6' of size 6" "note" }
+};
+
+void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
+{
+  char *p = pb4_b6->b6 + i;
+  char *q = pb4_b6->b4 + i;
+  char *d = MAX (p, q);
+
+  d[3] = 0;
+  d[4] = 0;
+  d[5] = 0;
+  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
index 0c7b53ccc0b..52467267a04 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
@@ -27,10 +27,10 @@ void max_a3_a5 (int i)
      by its own warning independently of -Wstringop-overflow.  */
   char *d = MAX (p, q);
 
-  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "" { target { i?86-*-* x86_64-*-* } } }
+  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "pr102706" { target { vect_slp_v4qi_store } } }
   d[3] = 0;
   d[4] = 0;
-  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
+  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "pr102706" { xfail { vect_slp_v4qi_store } } }
 }
 
 
@@ -44,10 +44,10 @@ void max_b6_b4 (int i)
   char *q = b4 + i;
   char *d = MAX (p, q);
 
-  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "" { target { i?86-*-* x86_64-*-* } } }
+  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of size 3" "pr102706" { target { vect_slp_v4qi_store } } }
   d[4] = 0;
   d[5] = 0;
-  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
+  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "pr102706" { xfail { vect_slp_v4qi_store } } }
 }
 
 
@@ -82,7 +82,8 @@ void max_d8_p (char *q, int i)
 struct A3_5
 {
   char a3[3];  // { dg-message "at offset 3 into destination object 'a3' of size 3" "pr??????" { xfail *-*-* } }
-  char a5[5];  // { dg-message "at offset 5 into destination object 'a5' of size 5" "note" { xfail { i?86-*-* x86_64-*-* } } }
+  // refer to pr102697 for xfail
+  char a5[5];  // { dg-message "at offset 5 into destination object 'a5' of size 5" "note" { xfail { vect_slp_v4qi_store } } }
 };
 
 void max_A3_A5 (int i, struct A3_5 *pa3_5)
@@ -95,14 +96,15 @@ void max_A3_A5 (int i, struct A3_5 *pa3_5)
   d[2] = 0;
   d[3] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "pr??????" { xfail *-*-* } }
   d[4] = 0;
-  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
+  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "pr102697" { xfail { vect_slp_v4qi_store } } }
 }
 
 
 struct B4_B6
 {
   char b4[4];
-  char b6[6];       // { dg-message "at offset \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6" "note" { xfail { i?86-*-* x86_64-*-* } } }
+  // refer to pr102697 for xfail
+  char b6[6];       // { dg-message "at offset \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6" "note" { xfail { vect_slp_v4qi_store } } }
 };
 
 void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
@@ -114,7 +116,7 @@ void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
   d[3] = 0;
   d[4] = 0;
   d[5] = 0;
-  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "" { xfail { i?86-*-* x86_64-*-* } } }
+  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size 0" "pr102697" { xfail { vect_slp_v4qi_store } } }
 }
 
 
diff --git a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
new file mode 100644
index 00000000000..8e023b7cfa7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
@@ -0,0 +1,45 @@
+/* Test to verify that -Wzero-length-bounds and not -Warray-bounds is
+   issued for accesses to interior zero-length array members that are
+   within the bounds of the enclosing struct.
+   { dg-do compile }
+   { dg-options "-O2 -Wall -fno-tree-vectorize" } */
+
+void sink (void*);
+
+struct A { int i; };
+struct B { int j; struct A a[0]; };
+
+struct C
+{
+  struct B b1;
+  struct B b2;
+};
+
+char cbuf1[1 * sizeof (struct C)];
+char cbuf2[2 * sizeof (struct C)] = { };
+
+void test_C_global_buf (void)
+{
+  struct C *p = (struct C*)&cbuf1;
+
+  p->b1.a[-1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
+  p->b1.a[ 0].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
+  p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
+  sink (p);
+
+  p->b2.a[ 0].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
+  p->b2.a[ 1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
+  sink (p);
+
+  p = (struct C*)&cbuf2;
+  p->b1.a[-1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
+  p->b1.a[ 0].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
+  p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
+  sink (p);
+
+  p->b2.a[ 0].i = 0;
+  p->b2.a[ 1].i = 0;
+  p->b2.a[ 2].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
+  p->b2.a[ 3].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
+  sink (p);
+}
diff --git a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
index 841b2bfa122..b2321495afc 100644
--- a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
+++ b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
@@ -87,7 +87,7 @@ void test_C_global_buf (void)
   p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
   sink (p);
 
-  p->b2.a[ 0].i = 0;
+  p->b2.a[ 0].i = 0;    // { dg-warning "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v2si_store &&  { ! vect_slp_v4si_store } } } }
   p->b2.a[ 1].i = 0;
   p->b2.a[ 2].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
   p->b2.a[ 3].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 9ebca7ac007..1c8b1ebb86e 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -7580,6 +7580,188 @@ proc check_effective_target_vect_element_align_preferred { } {
 		   && [check_effective_target_vect_variable_length] }]
 }
 
+# Return true if vectorization of v2qi/v4qi/v8qi/v16qi/v2hi store is enabed.
+# Return zero if the desirable pattern isn't found.
+# It's used by Warray-bounds/Wstringop-overflow testcases which are
+# regressed by O2 vectorization, refer to PR102697/PR102462/PR102706
+proc check_vect_slp_aligned_store_usage { pattern macro } {
+    global tool
+
+    set result [check_compile slp_aligned_store_usage assembly {
+	char a[16] __attribute__ ((aligned (16)));
+	short b[4] __attribute__((aligned(8)));
+	int c[4] __attribute__((aligned(16)));
+	#ifdef TEST_V8QI
+	void
+	foo ()
+	{
+	    a[0] = 0;
+	    a[1] = 1;
+	    a[2] = 2;
+	    a[3] = 3;
+	    a[4] = 4;
+	    a[5] = 5;
+	    a[6] = 6;
+	    a[7] = 7;
+	}
+	#elif TEST_V16QI
+	void
+	foo1 ()
+	{
+	    a[0] = 0;
+	    a[1] = 1;
+	    a[2] = 2;
+	    a[3] = 3;
+	    a[4] = 4;
+	    a[5] = 5;
+	    a[6] = 6;
+	    a[7] = 7;
+	    a[8] = 8;
+	    a[9] = 9;
+	    a[10] = 10;
+	    a[11] = 11;
+	    a[12] = 12;
+	    a[13] = 13;
+	    a[14] = 14;
+	    a[15] = 15;
+	}
+	#elif TEST_V4QI
+	void
+	foo2 ()
+	{
+	    a[0] = 0;
+	    a[1] = 1;
+	    a[2] = 2;
+	    a[3] = 3;
+	}
+	#elif TEST_V2QI
+	void
+	foo3 ()
+	{
+	    a[0] = 0;
+	    a[1] = 1;
+	}
+	#elif TEST_V2HI
+	void
+	foo4 ()
+	{
+	    b[0] = 0;
+	    b[1] = 1;
+	}
+	#elif TEST_V4HI
+	void
+	foo5 ()
+	{
+	    b[0] = 0;
+	    b[1] = 1;
+	    b[2] = 2;
+	    b[3] = 3;
+	}
+	#elif TEST_V2SI
+	void
+	foo6 ()
+	{
+	    c[0] = 0;
+	    c[1] = 1;
+	}
+	#elif TEST_V4SI
+	void
+	foo7 ()
+	{
+	    c[0] = 0;
+	    c[1] = 1;
+	    c[2] = 2;
+	    c[3] = 3;
+	}
+	#endif
+    } "-O2 -fopt-info-all -D$macro" ]
+
+      # Get compiler emitted messages and delete generated file.
+      set lines [lindex $result 0]
+      set output [lindex $result 1]
+      remote_file build delete $output
+
+      # Check pattern exits in lines, set it to zero if not found.
+      if { [regexp $pattern $lines] } then {
+        return 1
+      }
+
+    return 0
+}
+
+# Return the true if target support vectorization of 2-byte char stores
+# with 2-byte aligned address at plain O2.
+proc check_effective_target_vect_slp_v2qi_store { } {
+    set pattern {add new stmt: MEM <vector\(2\) char>}
+    set macro "TEST_V2QI"
+    return [check_cached_effective_target vect_slp_v2qi_store {
+	expr [check_vect_slp_aligned_store_usage $pattern $macro] }]
+
+}
+
+# Return the true if target support vectorization of 4-byte char stores
+# with 4-byte aligned address at plain O2.
+proc check_effective_target_vect_slp_v4qi_store { } {
+    set pattern {add new stmt: MEM <vector\(4\) char>}
+    set macro "TEST_V4QI"
+    return [check_cached_effective_target vect_slp_v4qi_store {
+	expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
+}
+
+# Return the true if target support vectorization of 8-byte char stores
+# with 8-byte aligned address at plain O2.
+proc check_effective_target_vect_slp_v8qi_store { } {
+    set pattern {add new stmt: MEM <vector\(8\) char>}
+    set macro "TEST_V8QI"
+    return [check_cached_effective_target vect_slp_v8qi_store {
+	expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
+}
+
+# Return the true if target support vectorization of 16-byte char stores
+# with 16-byte aligned address at plain O2.
+proc check_effective_target_vect_slp_v16qi_store { } {
+    set pattern {add new stmt: MEM <vector\(16\) char>}
+    set macro "TEST_V16QI"
+    return [check_cached_effective_target vect_slp_v16qi_store {
+	expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
+}
+
+# Return the true if target support vectorization of 4-byte short stores
+# with 4-byte aligned address at plain O2.
+proc check_effective_target_vect_slp_v2hi_store { } {
+    set pattern {add new stmt: MEM <vector\(2\) short int>}
+    set macro "TEST_V2HI"
+    return [check_cached_effective_target vect_slp_v2hi_store {
+	expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
+}
+
+# Return the true if target support vectorization of 8-byte short stores
+# with 8-byte aligned address at plain O2.
+proc check_effective_target_vect_slp_v4hi_store { } {
+    set pattern {add new stmt: MEM <vector\(4\) short int>}
+    set macro "TEST_V4HI"
+    return [check_cached_effective_target vect_slp_v4hi_store {
+	expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
+}
+
+# Return the true if target support vectorization of 8-byte int stores
+# with 8-byte aligned address at plain O2.
+proc check_effective_target_vect_slp_v2si_store { } {
+    set pattern {add new stmt: MEM <vector\(2\) int>}
+    set macro "TEST_V2SI"
+    return [check_cached_effective_target vect_slp_v2si_store {
+	expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
+}
+
+# Return the true if target support vectorization of 16-byte int stores
+# with 16-byte aligned address at plain O2.
+proc check_effective_target_vect_slp_v4si_store { } {
+    set pattern {add new stmt: MEM <vector\(4\) int>}
+    set macro "TEST_V4SI"
+    return [check_cached_effective_target vect_slp_v4si_store {
+	expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
+}
+
 # Return 1 if we can align stack data to the preferred vector alignment.
 
 proc check_effective_target_vect_align_stack_vars { } {
-- 
2.18.1


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] Adjust testcase for O2 vectorization.
  2021-10-19  9:03                           ` liuhongt
@ 2021-10-20 11:34                             ` Christophe Lyon
  2021-10-21  1:20                               ` Hongtao Liu
  0 siblings, 1 reply; 29+ messages in thread
From: Christophe Lyon @ 2021-10-20 11:34 UTC (permalink / raw)
  To: liuhongt; +Cc: GCC Patches

Hi,


On Tue, Oct 19, 2021 at 11:03 AM liuhongt via Gcc-patches <
gcc-patches@gcc.gnu.org> wrote:

> updated patch:
>   1. Add documents in doc/sourcebuild.texi (Effective-Target Keywords).
>   2. Reduce -novec.c testcases to contain only new failed parted which
> is caused by O2 vectorization.
>   3. Add PR in dg-warning comment.
>
> As discussed in [1], this patch add xfail/target selector to those
> testcases, also make a copy of them so that they can be tested w/o
> vectorization.
>
> Newly added xfail/target selectors are used to check the vectorization
> capability of continuous byte/double bytes storage, these scenarios
> are exactly the part of the testcases that regressed after O2
> vectorization.
>
> [1] https://gcc.gnu.org/pipermail/gcc-patches/2021-October/581456.html.
>
> gcc/ChangeLog
>
>         * doc/sourcebuild.texi (Effective-Target Keywords): Document
>         vect_slp_v2qi_store, vect_slp_v4qi_store, vect_slp_v8qi_store,
>         vect_slp_v16qi_store, vect_slp_v2hi_store,
>         vect_slp_v4hi_store, vect_slp_v2si_store, vect_slp_v4si_store.
>
> gcc/testsuite/ChangeLog
>
>         PR middle-end/102722
>         PR middle-end/102697
>         PR middle-end/102462
>         PR middle-end/102706
>         PR middle-end/102744
>         * c-c++-common/Wstringop-overflow-2.c: Adjust testcase with new
>         xfail/target selector.
>         * gcc.dg/Warray-bounds-51.c: Ditto.
>         * gcc.dg/Warray-parameter-3.c: Ditto.
>         * gcc.dg/Wstringop-overflow-14.c: Ditto.
>         * gcc.dg/Wstringop-overflow-21.c: Ditto.
>         * gcc.dg/Wstringop-overflow-68.c: Ditto.
>         * gcc.dg/Wstringop-overflow-76.c: Ditto.
>         * gcc.dg/Warray-bounds-48.c: Ditto.
>         * gcc.dg/Wzero-length-array-bounds-2.c: Ditto.
>

Some of these adjustments cause regressions on arm / aarch64, the exact
list depends on the target/flags.
See
https://people.linaro.org/~christophe.lyon/cross-validation/gcc/trunk/r12-4525-gf36240f8c835d792f788b6724e272fc0a4a4f26f/report-build-info.html
for more on details on several combinations.

Can you have a look?

Christophe

        * lib/target-supports.exp (check_vect_slp_aligned_store_usage):
>         New function.
>         (check_effective_target_vect_slp_v2qi_store): Ditto.
>         (check_effective_target_vect_slp_v4qi_store): Ditto.
>         (check_effective_target_vect_slp_v8qi_store): Ditto.
>         (check_effective_target_vect_slp_v16qi_store): Ditto.
>         (check_effective_target_vect_slp_v2hi_store): Ditto.
>         (check_effective_target_vect_slp_v4hi_store): Ditto.
>         (check_effective_target_vect_slp_v2si_store): Ditto.
>         (check_effective_target_vect_slp_v4si_store): Ditto.
>         * c-c++-common/Wstringop-overflow-2-novec.c: New test.
>         * gcc.dg/Warray-bounds-51-novec.c: New test.
>         * gcc.dg/Warray-bounds-48-novec.c: New test.
>         * gcc.dg/Warray-parameter-3-novec.c: New test.
>         * gcc.dg/Wstringop-overflow-14-novec.c: New test.
>         * gcc.dg/Wstringop-overflow-21-novec.c: New test.
>         * gcc.dg/Wstringop-overflow-76-novec.c: New test.
>         * gcc.dg/Wzero-length-array-bounds-2-novec.c: New test.
> ---
>  gcc/doc/sourcebuild.texi                      |  32 ++
>  .../c-c++-common/Wstringop-overflow-2-novec.c | 126 ++++++
>  .../c-c++-common/Wstringop-overflow-2.c       |  20 +-
>  gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c | 364 ++++++++++++++++++
>  gcc/testsuite/gcc.dg/Warray-bounds-48.c       |   4 +-
>  gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c |  21 +
>  gcc/testsuite/gcc.dg/Warray-bounds-51.c       |   2 +-
>  .../gcc.dg/Warray-parameter-3-novec.c         |  16 +
>  gcc/testsuite/gcc.dg/Warray-parameter-3.c     |   2 +-
>  .../gcc.dg/Wstringop-overflow-14-novec.c      |  16 +
>  gcc/testsuite/gcc.dg/Wstringop-overflow-14.c  |   4 +-
>  .../gcc.dg/Wstringop-overflow-21-novec.c      |  34 ++
>  gcc/testsuite/gcc.dg/Wstringop-overflow-21.c  |   8 +-
>  gcc/testsuite/gcc.dg/Wstringop-overflow-68.c  |  17 +-
>  .../gcc.dg/Wstringop-overflow-76-novec.c      |  88 +++++
>  gcc/testsuite/gcc.dg/Wstringop-overflow-76.c  |  18 +-
>  .../Wzero-length-array-bounds-2-novec.c       |  45 +++
>  .../gcc.dg/Wzero-length-array-bounds-2.c      |   2 +-
>  gcc/testsuite/lib/target-supports.exp         | 182 +++++++++
>  19 files changed, 967 insertions(+), 34 deletions(-)
>  create mode 100644 gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
>  create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
>  create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
>  create mode 100644 gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
>  create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
>  create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
>  create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
>  create mode 100644
> gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
>
> diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
> index b1fffd5e90f..6a165767630 100644
> --- a/gcc/doc/sourcebuild.texi
> +++ b/gcc/doc/sourcebuild.texi
> @@ -1845,6 +1845,38 @@ Target supports loop vectorization with partial
> vectors and
>  @item vect_partial_vectors
>  Target supports loop vectorization with partial vectors and
>  @code{vect-partial-vector-usage} is nonzero.
> +
> +@item vect_slp_v2qi_store
> +Target supports vectorization of 2-byte char stores with 2-byte aligned
> +address at plain @option{-O2}.
> +
> +@item vect_slp_v4qi_store
> +Target supports vectorization of 4-byte char stores with 4-byte aligned
> +address at plain @option{-O2}.
> +
> +@item vect_slp_v8qi_store
> +Target supports vectorization of 8-byte char stores with 8-byte aligned
> +address at plain @option{-O2}.
> +
> +@item vect_slp_v16qi_store
> +Target supports vectorization of 16-byte char stores with 16-byte aligned
> +address at plain @option{-O2}.
> +
> +@item vect_slp_v2hi_store
> +Target supports vectorization of 4-byte short stores with 4-byte aligned
> +address at plain @option{-O2}.
> +
> +@item vect_slp_v4hi_store
> +Target supports vectorization of 8-byte short stores with 8-byte aligned
> +address at plain @option{-O2}.
> +
> +@item vect_slp_v2si_store
> +Target supports vectorization of 8-byte int stores with 8-byte aligned
> +address at plain @option{-O2}.
> +
> +@item vect_slp_v4si_store
> +Target supports vectorization of 16-byte int stores with 16-byte aligned
> +address at plain @option{-O2}.
>  @end table
>
>  @subsubsection Thread Local Storage attributes
> diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> b/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> new file mode 100644
> index 00000000000..3c34ad35a5d
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> @@ -0,0 +1,126 @@
> +/* PR middle-end/91458 - inconsistent warning for writing past the end
> +   of an array member
> +   { dg-do compile }
> +   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds
> -fno-ipa-icf" } */
> +
> +void sink (void*);
> +
> +// Exercise trailing one-element array members.
> +
> +struct A1
> +{
> +  char n;
> +  char a[1];                    // { dg-message "destination object"
> "note" }
> +};
> +
> +// Verify warning for access to a definition with an initializer that
> doesn't
> +// initialize the one-element array member.
> +struct A1 a1__ = { 0 };
> +
> +void ga1__ (void)
> +{
> +  a1__.a[0] = 0;
> +  a1__.a[1] = 1;                 // { dg-warning
> "\\\[-Wstringop-overflow" }
> +  a1__.a[2] = 2;                 // { dg-warning
> "\\\[-Wstringop-overflow" }
> +
> +  struct A1 a = { 1 };
> +  a.a[0] = 0;
> +  a.a[1] = 1;                    // { dg-warning
> "\\\[-Wstringop-overflow" }
> +  a.a[2] = 2;                    // { dg-warning
> "\\\[-Wstringop-overflow" }
> +  sink (&a);
> +}
> +
> +// Verify warning for access to a definition with an initializer that
> +// initializes the one-element array member to empty.
> +struct A1 a1_0 = { 0, { } };
> +
> +void ga1_0_ (void)
> +{
> +  a1_0.a[0] = 0;
> +  a1_0.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow"
> }
> +  a1_0.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow"
> }
> +
> +  struct A1 a = { 1, { } };
> +  a.a[0] = 0;
> +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> }
> +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> }
> +  sink (&a);
> +}
> +
> +// Verify warning for access to a definition with an initializer that
> +// initializes the one-element array member.
> +struct A1 a1_1 = { 0, { 1 } };
> +
> +void ga1_1 (void)
> +{
> +  a1_1.a[0] = 0;
> +  a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow"
> }
> +  a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow"
> }
> +
> +  struct A1 a = { 0, { 1 } };
> +  a.a[0] = 0;
> +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> }
> +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> }
> +  sink (&a);
> +}
> +
> +// Exercise interior one-element array members (verify they're not
> +// treated as trailing.
> +
> +struct A1i
> +{
> +  char n;
> +  char a[1];                    // { dg-message "destination object" }
> +  char x;
> +};
> +
> +// Verify warning for access to a definition with an initializer that
> doesn't
> +// initialize the one-element array member.
> +struct A1i a1i__ = { 0 };
> +
> +void ga1i__ (void)
> +{
> +  a1i__.a[0] = 0;
> +  a1i__.a[1] = 1;                // { dg-warning
> "\\\[-Wstringop-overflow" }
> +  a1i__.a[2] = 2;                // { dg-warning
> "\\\[-Wstringop-overflow" }
> +
> +  struct A1i a = { 0 };
> +  a.a[0] = 0;
> +  a.a[1] = 1;                    // { dg-warning
> "\\\[-Wstringop-overflow" }
> +  a.a[2] = 2;                    // { dg-warning
> "\\\[-Wstringop-overflow" }
> +  sink (&a);
> +}
> +
> +// Verify warning for access to a definition with an initializer that
> +// initializes the one-element array member to empty.
> +struct A1 a1i_0 = { 0, { } };
> +
> +void ga1i_0_ (void)
> +{
> +  a1i_0.a[0] = 0;
> +  a1i_0.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow"
> }
> +  a1i_0.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow"
> }
> +
> +  struct A1 a = { 0, { } };
> +  a.a[0] = 0;
> +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> }
> +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> }
> +  sink (&a);
> +}
> +
> +// Verify warning for access to a definition with an initializer that
> +// initializes the one-element array member.
> +struct A1 a1i_1 = { 0, { 1 } };
> +
> +void ga1i_1 (void)
> +{
> +  a1i_1.a[0] = 0;
> +  a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow"
> }
> +  a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow"
> }
> +
> +  struct A1 a = { 0, { 1 } };
> +  a.a[0] = 1;
> +  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> }
> +  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow"
> }
> +  sink (&a);
> +}
> diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> index 7d29b5f48c7..ca38bda73f5 100644
> --- a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> +++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> @@ -190,7 +190,7 @@ void ga1__ (void)
>    struct A1 a = { 1 };
>    a.a[0] = 0;
>    a.a[1] = 1;                    // { dg-warning
> "\\\[-Wstringop-overflow" }
> -  a.a[2] = 2;                    // { dg-warning
> "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  a.a[2] = 2;                    // { dg-warning
> "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store } } }
>    sink (&a);
>  }
>
> @@ -207,7 +207,7 @@ void ga1_0_ (void)
>    struct A1 a = { 1, { } };
>    a.a[0] = 0;
>    a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> }
> -  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> "" { xfail { i?86-*-* x86_64-*-* } } }
> +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> "pr102462" { xfail { vect_slp_v2qi_store } } }
>    sink (&a);
>  }
>
> @@ -221,10 +221,10 @@ void ga1_1 (void)
>    a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow"
> }
>    a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow"
> }
>
> -  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> "" { target { i?86-*-* x86_64-*-* } } }
> +  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> "pr102706" { target { vect_slp_v4qi_store } } }
>    a.a[0] = 0;
> -  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> "" { xfail { i?86-*-* x86_64-*-* } } }
> -  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> "" { xfail { i?86-*-* x86_64-*-* } } }
> +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> "" { xfail { vect_slp_v4qi_store } } }
> +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> "" { xfail { vect_slp_v4qi_store } } }
>    sink (&a);
>  }
>
> @@ -289,7 +289,7 @@ void ga1i__ (void)
>    struct A1i a = { 0 };
>    a.a[0] = 0;
>    a.a[1] = 1;                    // { dg-warning
> "\\\[-Wstringop-overflow" }
> -  a.a[2] = 2;                    // { dg-warning
> "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  a.a[2] = 2;                    // { dg-warning
> "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store } } }
>    sink (&a);
>  }
>
> @@ -306,7 +306,7 @@ void ga1i_0_ (void)
>    struct A1 a = { 0, { } };
>    a.a[0] = 0;
>    a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> }
> -  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> "" { xfail { i?86-*-* x86_64-*-* } } }
> +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> "pr102462" { xfail { vect_slp_v2qi_store } } }
>    sink (&a);
>  }
>
> @@ -320,10 +320,10 @@ void ga1i_1 (void)
>    a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow"
> }
>    a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow"
> }
>
> -  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> "" { target { i?86-*-* x86_64-*-* } } }
> +  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> "pr102462" { target { vect_slp_v4qi_store } } }
>    a.a[0] = 1;
> -  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> "" { xfail { i?86-*-* x86_64-*-* } } }
> -  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow"
> "" { xfail { i?86-*-* x86_64-*-* } } }
> +  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> "pr102462" { xfail { vect_slp_v4qi_store } } }
> +  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow"
> "pr102462" { xfail { vect_slp_v4qi_store } } }
>    sink (&a);
>  }
>
> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> new file mode 100644
> index 00000000000..da179a2c0f5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> @@ -0,0 +1,364 @@
> +/* PR middle-end/91647 - missing -Warray-bounds accessing a zero-length
> array
> +   of a declared object
> +   { dg-do "compile" }
> +   { dg-options "-O2 -Wall -fno-tree-vectorize" }
> +   { dg-require-effective-target alloca } */
> +
> +typedef __INT16_TYPE__ int16_t;
> +typedef __INT32_TYPE__ int32_t;
> +
> +void sink (void*);
> +
> +/* Exercise a true flexible member.  */
> +
> +struct AX
> +{
> +  int32_t n;
> +  int16_t ax[];     // { dg-message "while referencing 'ax'" "member" }
> +};
> +
> +static void warn_ax_local (struct AX *p)
> +{
> +  p->ax[0] = 0;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->ax[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void nowarn_ax_extern (struct AX *p)
> +{
> +  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
> +}
> +
> +static void warn_ax_local_buf (struct AX *p)
> +{
> +  p->ax[0] = 4; p->ax[1] = 5;
> +
> +  p->ax[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->ax[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->ax[4] = 8;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_ax_extern_buf (struct AX *p)
> +{
> +  p->ax[0] = 9; p->ax[1] = 10; p->ax[2] = 11;
> +
> +  p->ax[3] = 12;    // { dg-warning "\\\[-Warray-bounds" }
> +  p->ax[4] = 13;    // { dg-warning "\\\[-Warray-bounds" }
> +  p->ax[5] = 14;    // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void nowarn_ax_extern_bufx (struct AX *p)
> +{
> +  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
> +}
> +
> +static void nowarn_ax_ref (struct AX *p)
> +{
> +  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
> +}
> +
> +void test_ax (struct AX *p, unsigned n)
> +{
> +  {
> +    struct AX sax;  // { dg-message "defined here" "struct definition" }
> +    warn_ax_local (&sax);
> +    sink (&sax);
> +  }
> +
> +  {
> +    extern
> +      struct AX xsax;
> +    nowarn_ax_extern (&xsax);
> +    sink (&xsax);
> +  }
> +
> +  {
> +    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
> +    char ax_buf_p2[sizeof (struct AX) + 2 * sizeof (int16_t)];
> +    warn_ax_local_buf ((struct AX*) ax_buf_p2);
> +    sink (ax_buf_p2);
> +  }
> +
> +  {
> +    /* Verify out-of-bounds access to the extern BUF with a known
> +       bound is diagnosed.  */
> +    extern char ax_buf_p3[sizeof (struct AX) + 3 * sizeof (int16_t)];
> +    warn_ax_extern_buf ((struct AX*) ax_buf_p3);
> +    sink (ax_buf_p3);
> +  }
> +
> +  {
> +    /* Verify that accesses to BUFX with an unknown bound are not
> +       diagnosed.  */
> +    extern char bufx[];
> +    nowarn_ax_extern_bufx ((struct AX*) bufx);
> +    sink (bufx);
> +  }
> +
> +  {
> +    /* Verify that accesses to BUFN with a runtime bound are not
> +       diagnosed.  */
> +    char bufn[n];
> +    nowarn_ax_extern_bufx ((struct AX*) bufn);
> +    sink (bufn);
> +  }
> +
> +  nowarn_ax_ref (p);
> +}
> +
> +
> +/* Exercise a zero-length trailing member array.  It's the same as above
> +   except that extern declarations with no definitions are considered to
> +   have zero elements (they can't be initialized to have any).  */
> +
> +struct A0
> +{
> +  int32_t n;
> +  int16_t a0[0];    // { dg-message "while referencing 'a0'" "member" }
> +};
> +
> +static void warn_a0_local (struct A0 *p)
> +{
> +  p->a0[0] = 0;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a0[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a0_extern (struct A0 *p)
> +{
> +  p->a0[0] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a0[1] = 3;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a0_local_buf (struct A0 *p)
> +{
> +  p->a0[0] = 4; p->a0[1] = 5;
> +
> +  p->a0[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a0[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a0[4] = 8;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a0_extern_buf (struct A0 *p)
> +{
> +  p->a0[0] = 9; p->a0[1] = 10; p->a0[2] = 11;
> +
> +  p->a0[3] = 12;    // { dg-warning "\\\[-Warray-bounds" }
> +  p->a0[4] = 13;    // { dg-warning "\\\[-Warray-bounds" }
> +  p->a0[5] = 14;    // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void nowarn_a0_extern_bufx (struct A0 *p)
> +{
> +  p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
> +}
> +
> +static void nowarn_a0_ref (struct A0 *p)
> +{
> +  p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
> +}
> +
> +void test_a0 (struct A0 *p, unsigned n)
> +{
> +  {
> +    struct A0 sa0;  // { dg-message "defined here" "struct definition" }
> +    warn_a0_local (&sa0);
> +    sink (&sa0);
> +  }
> +
> +  {
> +    extern
> +      struct A0 xsa0;  // { dg-message "defined here" "struct definition"
> }
> +    warn_a0_extern (&xsa0);
> +    sink (&xsa0);
> +  }
> +
> +  {
> +    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
> +    char a0_buf_p2[sizeof (struct A0) + 2 * sizeof (int16_t)];
> +    warn_a0_local_buf ((struct A0*) a0_buf_p2);
> +    sink (a0_buf_p2);
> +  }
> +
> +  {
> +    /* Verify out-of-bounds access to the extern BUF with a known
> +       bound is diagnosed.  */
> +    extern char a0_buf_p3[sizeof (struct A0) + 3 * sizeof (int16_t)];
> +    warn_a0_extern_buf ((struct A0*) a0_buf_p3);
> +    sink (a0_buf_p3);
> +  }
> +
> +  {
> +    /* Verify that accesses to BUFX with an unknown bound are not
> +       diagnosed.  */
> +    extern char bufx[];
> +    nowarn_a0_extern_bufx ((struct A0*) bufx);
> +    sink (bufx);
> +  }
> +
> +  {
> +    /* Verify that accesses to BUFN with a runtime bound are not
> +       diagnosed.  */
> +    char bufn[n];
> +    nowarn_a0_extern_bufx ((struct A0*) bufn);
> +    sink (bufn);
> +  }
> +
> +  nowarn_a0_ref (p);
> +}
> +
> +
> +/* Exercise a one-element trailing member array.  It's the same as above
> +   except that it has exactly one element.  */
> +
> +struct A1
> +{
> +  int32_t n;
> +  int16_t a1[1];    // { dg-message "while referencing 'a1'" }
> +};
> +
> +static void warn_a1_local_noinit (struct A1 *p)
> +{
> +  p->a1[0] = 0;
> +  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a1_extern (struct A1 *p)
> +{
> +  p->a1[0] = 0;
> +  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a1_init (struct A1 *p)
> +{
> +  p->a1[0] = 0;
> +  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a1_local_buf (struct A1 *p)
> +{
> +  p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3;
> +
> +  p->a1[4] = 4;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a1_extern_buf (struct A1 *p)
> +{
> +  p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3; p->a1[4] = 4;
> +
> +  p->a1[5] = 5;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void nowarn_a1_extern_bufx (struct A1 *p)
> +{
> +  p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
> +}
> +
> +static void nowarn_a1_ref (struct A1 *p)
> +{
> +  p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
> +}
> +
> +void test_a1 (struct A1 *p, unsigned n)
> +{
> +  {
> +    struct A1 a1;
> +    warn_a1_local_noinit (&a1);
> +    sink (&a1);
> +  }
> +
> +  {
> +    extern struct A1 a1x;
> +    warn_a1_extern (&a1x);
> +    sink (&a1x);
> +}
> +  {
> +    struct A1 a1 = { 0, { 1 } };
> +    warn_a1_init (&a1);
> +    sink (&a1);
> +  }
> +
> +  {
> +    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
> +    char buf_p2[sizeof (struct A1) + 2 * sizeof (int16_t)];
> +    warn_a1_local_buf ((struct A1*) buf_p2);
> +    sink (buf_p2);
> +  }
> +
> +  {
> +    /* Verify out-of-bounds access to the extern BUF with a known
> +       bound is diagnosed.  */
> +    extern char a1_buf_p3[sizeof (struct A1) + 3 * sizeof (int16_t)];
> +    warn_a1_extern_buf ((struct A1*) a1_buf_p3);
> +    sink (a1_buf_p3);
> +  }
> +
> +  {
> +    /* Verify that accesses to BUFX with an unknown bound are not
> +       diagnosed.  */
> +    extern char bufx[];
> +    nowarn_a1_extern_bufx ((struct A1*) bufx);
> +    sink (bufx);
> +  }
> +
> +  {
> +    /* Verify that accesses to BUFN with a runtime bound are not
> +       diagnosed.  */
> +    char bufn[n];
> +    nowarn_a1_extern_bufx ((struct A1*) bufn);
> +    sink (bufn);
> +  }
> +
> +  nowarn_a1_ref (p);
> +}
> +
> +
> +/* Exercise a two-element trailing member array.  It's treated
> +   the same as an interior array member.  */
> +
> +struct A2
> +{
> +  int32_t n;
> +  int16_t a2[2];    // { dg-message "while referencing 'a2'" }
> +};
> +
> +static void warn_a2_noinit (struct A2 *p)
> +{
> +  p->a2[0] = 0; p->a2[1] = 1;
> +
> +  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a2_init (struct A2 *p)
> +{
> +  p->a2[0] = 0; p->a2[1] = 1;
> +
> +  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a2[9] = 9;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +static void warn_a2_ref (struct A2 *p)
> +{
> +  p->a2[0] = 0; p->a2[1] = 1;
> +
> +  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->a2[9] = 9;     // { dg-warning "\\\[-Warray-bounds" }
> +}
> +
> +void test_a2 (struct A2 *p)
> +{
> +  {
> +    struct A2 a2;
> +    warn_a2_noinit (&a2);
> +    sink (&a2);
> +  }
> +
> +  {
> +    struct A2 a2 = { 0, { 1, 2 } };
> +    warn_a2_init (&a2);
> +    sink (&a2);
> +  }
> +
> +  warn_a2_ref (p);
> +}
> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> index 13373d1e99e..19b7634c063 100644
> --- a/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> @@ -30,7 +30,7 @@ static void nowarn_ax_extern (struct AX *p)
>
>  static void warn_ax_local_buf (struct AX *p)
>  {
> -  p->ax[0] = 4; p->ax[1] = 5;
> +  p->ax[0] = 4; p->ax[1] = 5;  // { dg-warning "\\\[-Wstringop-overflow"
> "pr102706" { target { vect_slp_v2hi_store &&  { ! vect_slp_v4hi_store } } }
> }
>
>    p->ax[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
>    p->ax[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> @@ -130,7 +130,7 @@ static void warn_a0_extern (struct A0 *p)
>
>  static void warn_a0_local_buf (struct A0 *p)
>  {
> -  p->a0[0] = 4; p->a0[1] = 5;
> +  p->a0[0] = 4; p->a0[1] = 5;  // { dg-warning "\\\[-Wstringop-overflow"
> "pr102706" { target { vect_slp_v2hi_store && { ! vect_slp_v4hi_store } } } }
>
>    p->a0[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
>    p->a0[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> b/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> new file mode 100644
> index 00000000000..ef8056d9b7f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> @@ -0,0 +1,21 @@
> +/* PR middle-end/92333 - missing variable name referencing VLA in warnings
> +   PR middle-end/82608 - missing -Warray-bounds on an out-of-bounds VLA
> index
> +   { dg-do compile }
> +   { dg-options "-O2 -Wall -fno-tree-vectorize" }  */
> +
> +void sink (void*);
> +
> +void test_struct_char_vla_location (void)
> +{
> +  unsigned nelts = 7;
> +
> +  struct {
> +    char cvla[nelts]; // { dg-message "declared here|while referencing" }
> +  } s;
> +
> +  s.cvla[0] = __LINE__;
> +  s.cvla[nelts - 1] = 0;
> +  s.cvla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
> +
> +  sink (&s);
> +}
> diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> b/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> index de60d87ab95..8b589f38191 100644
> --- a/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> +++ b/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> @@ -39,7 +39,7 @@ void test_struct_char_vla_location (void)
>    } s;
>
>    s.cvla[0] = __LINE__;
> -  s.cvla[nelts - 1] = 0; // { dg-warning "\\\[-Wstringop-overflow" "" {
> target { i?86-*-* x86_64-*-* } } }
> +  s.cvla[nelts - 1] = 0; // { dg-warning "\\\[-Wstringop-overflow"
> "pr102706" { target { vect_slp_v2qi_store } } }
>    s.cvla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
>
>    sink (&s);
> diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> b/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> new file mode 100644
> index 00000000000..5089d555392
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> @@ -0,0 +1,16 @@
> +/* PR c/50584 - No warning for passing small array to C99 static array
> +   declarator
> +   { dg-do compile }
> +   { dg-options "-Wall -Warray-parameter=1" } */
> +
> +/* Also verify that -Warray-bounds doesn't trigger for ordinary array
> +   parameters...  */
> +#pragma GCC optimize ("2,no-tree-vectorize")
> +
> +/* ...but does for static arrays.  */
> +__attribute__ ((noipa)) void
> +gcas3 (char a[static 3])
> +{
> +  a[0] = 0; a[1] = 1; a[2] = 2;
> +  a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
> +}
> diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> index e8a269c85c6..b6ed8daf51c 100644
> --- a/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> +++ b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> @@ -77,7 +77,7 @@ gia3 (int a[3])
>  __attribute__ ((noipa)) void
>  gcas3 (char a[static 3])
>  {
> -  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow"
> "" { target { i?86-*-* x86_64-*-* } } }
> +  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow"
> "pr102706" { target { vect_slp_v4qi_store } } }
>    a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
>  }
>
> diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> b/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> new file mode 100644
> index 00000000000..de39eaaeb95
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> @@ -0,0 +1,16 @@
> +/* Test to verify that past-the-end multibyte writes via lvalues of wider
> +   types than char are diagnosed.
> +   { dg-do compile }
> +   { dg-require-effective-target int32plus }
> +   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds" }  */
> +
> +typedef __INT16_TYPE__  int16_t;
> +
> +char a4[4], a8[8], a16[16];
> +
> +void test_int16 (void)
> +{
> +  char *p = a4 + 1;
> +  *(int16_t*)p = 0;
> +  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a
> region of size 1" }
> +}
> diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> index 7683084e46e..c4a3f05d883 100644
> --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> @@ -36,8 +36,8 @@ void test_memcpy_cond (int i)
>  void test_int16 (void)
>  {
>    char *p = a4 + 1;
> -  *(int16_t*)p = 0;    // { dg-warning "writing 4 bytes into a region of
> size 3" "" { target { i?86-*-* x86_64-*-* } } }
> -  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a
> region of size 1" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  *(int16_t*)p = 0;    // { dg-warning "writing 4 bytes into a region of
> size 3" "pr102706" { target { vect_slp_v2hi_store } } }
> +  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a
> region of size 1" "pr102706" { xfail { vect_slp_v2hi_store } } }
>  }
>
>
> diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> b/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> new file mode 100644
> index 00000000000..6f83548e902
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> @@ -0,0 +1,34 @@
> +/* PR middle-end/92312 - bogus -Wstringop-overflow storing into a trailing
> +   array backed by larger buffer
> +   { dg-do compile }
> +   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds" } */
> +
> +struct S0 { char a, b[0]; };
> +
> +void sink (void*);
> +
> +void test_store_zero_length (int i)
> +{
> +  char a[3];
> +  struct S0 *p = (struct S0*)a;
> +  p->a = 0;
> +  p->b[0] = 0;
> +  p->b[1] = 1;                      // { dg-bogus
> "\\\[-Wstringop-overflow" }
> +  p->b[2] = 2;                      // { dg-warning
> "\\\[-Wstringop-overflow" }
> +  p->b[i] = 2;
> +  sink (p);
> +}
> +
> +struct Sx { char a, b[]; };
> +
> +void test_store_flexarray (int i)
> +{
> +  char a[3];
> +  struct Sx *p = (struct Sx*)a;
> +  p->a = 0;
> +  p->b[0] = 0;
> +  p->b[1] = 1;                      // { dg-bogus
> "\\\[-Wstringop-overflow" }
> +  p->b[2] = 1;                      // { dg-warning
> "\\\[-Wstringop-overflow" }
> +  p->b[i] = 2;
> +  sink (p);
> +}
> diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> index d88bde9c740..3fccfc9a798 100644
> --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> @@ -23,10 +23,10 @@ void test_store_zero_length (int i)
>  {
>    char a[3];
>    struct S0 *p = (struct S0*)a;
> -  p->a = 0;                         // { dg-warning
> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> +  p->a = 0;                         // { dg-warning
> "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v4qi_store } } }
>    p->b[0] = 0;
>    p->b[1] = 1;                      // { dg-bogus
> "\\\[-Wstringop-overflow" }
> -  p->b[2] = 2;                      // { dg-warning
> "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  p->b[2] = 2;                      // { dg-warning
> "\\\[-Wstringop-overflow" "pr102706" { xfail { vect_slp_v4qi_store } } }
>    p->b[i] = 2;
>    sink (p);
>  }
> @@ -50,10 +50,10 @@ void test_store_flexarray (int i)
>  {
>    char a[3];
>    struct Sx *p = (struct Sx*)a;
> -  p->a = 0;                         // { dg-warning
> "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> +  p->a = 0;                         // { dg-warning
> "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v4qi_store } } }
>    p->b[0] = 0;
>    p->b[1] = 1;                      // { dg-bogus
> "\\\[-Wstringop-overflow" }
> -  p->b[2] = 1;                      // { dg-warning
> "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  p->b[2] = 1;                      // { dg-warning
> "\\\[-Wstringop-overflow" "pr102706" { xfail { vect_slp_v4qi_store } } }
>    p->b[i] = 2;
>    sink (p);
>  }
> diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> index 09df0004991..04e91afb8bc 100644
> --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> @@ -58,11 +58,18 @@ void warn_comp_lit_zero (void)
>  void warn_comp_lit (void)
>  {
>    *(AC2*)a1 = Ac2;      // { dg-warning "writing 2 bytes into a region of
> size 1" "pr101475" { xfail *-*-* } }
> -  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> size 2" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> -  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> size 3" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> -  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> size 4" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> -  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> size 7" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> -  *(AC16*)a15 = Ac16;   // { dg-warning "writing 16 bytes into a region
> of size 15" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> +  // After vectorization, below codes are optimized to
> +  // MEM <vector(4) char> [(char *)&a2] = { 0, 1, 2, 3 };
> +  // MEM <vector(4) char> [(char *)&a3] = { 0, 1, 2, 3 };
> +  // MEM <vector(8) char> [(char *)&a4] = { 0, 1, 2, 3, 4, 5, 6, 7 };
> +  // MEM <vector(8) char> [(char *)&a7] = { 0, 1, 2, 3, 4, 5, 6, 7 };
> +  // MEM <vector(16) char> [(char *)&a15] = { 0, 1, 2, 3, 4, 5, 6, 7, 8,
> 9, 10, 11, 12, 13, 14, 15 };
> +  // and warning should be expected, refer to PR102722.
> +  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> size 2" "pr101475" { xfail { ! { vect_slp_v4qi_store } } } }
> +  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> size 3" "pr101475" { xfail { ! { vect_slp_v4qi_store } } } }
> +  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> size 4" "pr101475" { xfail { ! { vect_slp_v8qi_store } } } }
> +  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> size 7" "pr101475" { xfail { ! { vect_slp_v8qi_store } } } }
> +  *(AC16*)a15 = Ac16;   // { dg-warning "writing 16 bytes into a region
> of size 15" "pr101475" { xfail { ! { vect_slp_v16qi_store } } } }
>  }
>
>  void warn_aggr_decl (void)
> diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> new file mode 100644
> index 00000000000..71c643b62fb
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> @@ -0,0 +1,88 @@
> +/* Verify warnings and notes for MAX_EXPRs involving either pointers
> +   to distinct objects or one to a known object and the other to
> +   an unknown one.  Unlike for the same object, for unrelated objects
> +   the expected warnings and notes are the same as for MIN_EXPR: when
> +   the order of the objects in the address space cannot be determined
> +   the larger of them is assumed to be used.  (This is different for
> +   distinct struct members where the order is given.)
> +   The relational expressions are strictly invalid but that should be
> +   diagnosed by a separate warning.
> +   { dg-do compile }
> +   { dg-options "-O2 -Wno-array-bounds -fno-tree-vectorize" } */
> +
> +#define MAX(p, q) ((p) > (q) ? (p) : (q))
> +
> +/* Verify that even for MAX_EXPR and like for MIN_EXPR, the note points
> +   to the larger of the two objects and mentions the offset into it
> +   (although the offset might be better included in the warning).  */
> +extern char a3[3];
> +extern char a5[5];  // { dg-message "at offset 5 into destination object
> 'a5' of size 5" "note" }
> +
> +void max_a3_a5 (int i)
> +{
> +  char *p = a3 + i;
> +  char *q = a5 + i;
> +
> +  /* The relational expression below is invalid and should be diagnosed
> +     by its own warning independently of -Wstringop-overflow.  */
> +  char *d = MAX (p, q);
> +
> +  d[2] = 0;
> +  d[3] = 0;
> +  d[4] = 0;
> +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> 0" }
> +}
> +
> +
> +// Same as above but with the larger array as the first MAX_EXPR operand.
> +extern char b4[4];
> +extern char b6[6];  // { dg-message "at offset 6 into destination object
> 'b6' of size 6" "note" }
> +
> +void max_b6_b4 (int i)
> +{
> +  char *p = b6 + i;
> +  char *q = b4 + i;
> +  char *d = MAX (p, q);
> +
> +  d[3] = 0;
> +  d[4] = 0;
> +  d[5] = 0;
> +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> 0" }
> +}
> +
> +struct A3_5
> +{
> +  char a3[3];  // { dg-message "at offset 3 into destination object 'a3'
> of size 3" "pr??????" { xfail *-*-* } }
> +  char a5[5];  // { dg-message "at offset 5 into destination object 'a5'
> of size 5" "note" }
> +};
> +
> +void max_A3_A5 (int i, struct A3_5 *pa3_5)
> +{
> +  char *p = pa3_5->a3 + i;
> +  char *q = pa3_5->a5 + i;
> +
> +  char *d = MAX (p, q);
> +  d[2] = 0;
> +  d[3] = 0;         // { dg-warning "writing 1 byte into a region of size
> 0" "pr??????" { xfail *-*-* } }
> +  d[4] = 0;
> +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> 0" }
> +}
> +
> +
> +struct B4_B6
> +{
> +  char b4[4];
> +  char b6[6];       // { dg-message "at offset 6 into destination object
> 'b6' of size 6" "note" }
> +};
> +
> +void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
> +{
> +  char *p = pb4_b6->b6 + i;
> +  char *q = pb4_b6->b4 + i;
> +  char *d = MAX (p, q);
> +
> +  d[3] = 0;
> +  d[4] = 0;
> +  d[5] = 0;
> +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> 0" }
> +}
> diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> index 0c7b53ccc0b..52467267a04 100644
> --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> @@ -27,10 +27,10 @@ void max_a3_a5 (int i)
>       by its own warning independently of -Wstringop-overflow.  */
>    char *d = MAX (p, q);
>
> -  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of
> size 3" "" { target { i?86-*-* x86_64-*-* } } }
> +  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of
> size 3" "pr102706" { target { vect_slp_v4qi_store } } }
>    d[3] = 0;
>    d[4] = 0;
> -  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> 0" "pr102706" { xfail { vect_slp_v4qi_store } } }
>  }
>
>
> @@ -44,10 +44,10 @@ void max_b6_b4 (int i)
>    char *q = b4 + i;
>    char *d = MAX (p, q);
>
> -  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of
> size 3" "" { target { i?86-*-* x86_64-*-* } } }
> +  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of
> size 3" "pr102706" { target { vect_slp_v4qi_store } } }
>    d[4] = 0;
>    d[5] = 0;
> -  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> 0" "pr102706" { xfail { vect_slp_v4qi_store } } }
>  }
>
>
> @@ -82,7 +82,8 @@ void max_d8_p (char *q, int i)
>  struct A3_5
>  {
>    char a3[3];  // { dg-message "at offset 3 into destination object 'a3'
> of size 3" "pr??????" { xfail *-*-* } }
> -  char a5[5];  // { dg-message "at offset 5 into destination object 'a5'
> of size 5" "note" { xfail { i?86-*-* x86_64-*-* } } }
> +  // refer to pr102697 for xfail
> +  char a5[5];  // { dg-message "at offset 5 into destination object 'a5'
> of size 5" "note" { xfail { vect_slp_v4qi_store } } }
>  };
>
>  void max_A3_A5 (int i, struct A3_5 *pa3_5)
> @@ -95,14 +96,15 @@ void max_A3_A5 (int i, struct A3_5 *pa3_5)
>    d[2] = 0;
>    d[3] = 0;         // { dg-warning "writing 1 byte into a region of size
> 0" "pr??????" { xfail *-*-* } }
>    d[4] = 0;
> -  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> 0" "pr102697" { xfail { vect_slp_v4qi_store } } }
>  }
>
>
>  struct B4_B6
>  {
>    char b4[4];
> -  char b6[6];       // { dg-message "at offset
> \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6"
> "note" { xfail { i?86-*-* x86_64-*-* } } }
> +  // refer to pr102697 for xfail
> +  char b6[6];       // { dg-message "at offset
> \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6"
> "note" { xfail { vect_slp_v4qi_store } } }
>  };
>
>  void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
> @@ -114,7 +116,7 @@ void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
>    d[3] = 0;
>    d[4] = 0;
>    d[5] = 0;
> -  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> 0" "pr102697" { xfail { vect_slp_v4qi_store } } }
>  }
>
>
> diff --git a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
> b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
> new file mode 100644
> index 00000000000..8e023b7cfa7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
> @@ -0,0 +1,45 @@
> +/* Test to verify that -Wzero-length-bounds and not -Warray-bounds is
> +   issued for accesses to interior zero-length array members that are
> +   within the bounds of the enclosing struct.
> +   { dg-do compile }
> +   { dg-options "-O2 -Wall -fno-tree-vectorize" } */
> +
> +void sink (void*);
> +
> +struct A { int i; };
> +struct B { int j; struct A a[0]; };
> +
> +struct C
> +{
> +  struct B b1;
> +  struct B b2;
> +};
> +
> +char cbuf1[1 * sizeof (struct C)];
> +char cbuf2[2 * sizeof (struct C)] = { };
> +
> +void test_C_global_buf (void)
> +{
> +  struct C *p = (struct C*)&cbuf1;
> +
> +  p->b1.a[-1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->b1.a[ 0].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
> +  p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> +  sink (p);
> +
> +  p->b2.a[ 0].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->b2.a[ 1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> +  sink (p);
> +
> +  p = (struct C*)&cbuf2;
> +  p->b1.a[-1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->b1.a[ 0].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
> +  p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
> +  sink (p);
> +
> +  p->b2.a[ 0].i = 0;
> +  p->b2.a[ 1].i = 0;
> +  p->b2.a[ 2].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> +  p->b2.a[ 3].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> +  sink (p);
> +}
> diff --git a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> index 841b2bfa122..b2321495afc 100644
> --- a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> +++ b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> @@ -87,7 +87,7 @@ void test_C_global_buf (void)
>    p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
>    sink (p);
>
> -  p->b2.a[ 0].i = 0;
> +  p->b2.a[ 0].i = 0;    // { dg-warning "\\\[-Wstringop-overflow"
> "pr102706" { target { vect_slp_v2si_store &&  { ! vect_slp_v4si_store } } }
> }
>    p->b2.a[ 1].i = 0;
>    p->b2.a[ 2].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
>    p->b2.a[ 3].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> diff --git a/gcc/testsuite/lib/target-supports.exp
> b/gcc/testsuite/lib/target-supports.exp
> index 9ebca7ac007..1c8b1ebb86e 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -7580,6 +7580,188 @@ proc
> check_effective_target_vect_element_align_preferred { } {
>                    && [check_effective_target_vect_variable_length] }]
>  }
>
> +# Return true if vectorization of v2qi/v4qi/v8qi/v16qi/v2hi store is
> enabed.
> +# Return zero if the desirable pattern isn't found.
> +# It's used by Warray-bounds/Wstringop-overflow testcases which are
> +# regressed by O2 vectorization, refer to PR102697/PR102462/PR102706
> +proc check_vect_slp_aligned_store_usage { pattern macro } {
> +    global tool
> +
> +    set result [check_compile slp_aligned_store_usage assembly {
> +       char a[16] __attribute__ ((aligned (16)));
> +       short b[4] __attribute__((aligned(8)));
> +       int c[4] __attribute__((aligned(16)));
> +       #ifdef TEST_V8QI
> +       void
> +       foo ()
> +       {
> +           a[0] = 0;
> +           a[1] = 1;
> +           a[2] = 2;
> +           a[3] = 3;
> +           a[4] = 4;
> +           a[5] = 5;
> +           a[6] = 6;
> +           a[7] = 7;
> +       }
> +       #elif TEST_V16QI
> +       void
> +       foo1 ()
> +       {
> +           a[0] = 0;
> +           a[1] = 1;
> +           a[2] = 2;
> +           a[3] = 3;
> +           a[4] = 4;
> +           a[5] = 5;
> +           a[6] = 6;
> +           a[7] = 7;
> +           a[8] = 8;
> +           a[9] = 9;
> +           a[10] = 10;
> +           a[11] = 11;
> +           a[12] = 12;
> +           a[13] = 13;
> +           a[14] = 14;
> +           a[15] = 15;
> +       }
> +       #elif TEST_V4QI
> +       void
> +       foo2 ()
> +       {
> +           a[0] = 0;
> +           a[1] = 1;
> +           a[2] = 2;
> +           a[3] = 3;
> +       }
> +       #elif TEST_V2QI
> +       void
> +       foo3 ()
> +       {
> +           a[0] = 0;
> +           a[1] = 1;
> +       }
> +       #elif TEST_V2HI
> +       void
> +       foo4 ()
> +       {
> +           b[0] = 0;
> +           b[1] = 1;
> +       }
> +       #elif TEST_V4HI
> +       void
> +       foo5 ()
> +       {
> +           b[0] = 0;
> +           b[1] = 1;
> +           b[2] = 2;
> +           b[3] = 3;
> +       }
> +       #elif TEST_V2SI
> +       void
> +       foo6 ()
> +       {
> +           c[0] = 0;
> +           c[1] = 1;
> +       }
> +       #elif TEST_V4SI
> +       void
> +       foo7 ()
> +       {
> +           c[0] = 0;
> +           c[1] = 1;
> +           c[2] = 2;
> +           c[3] = 3;
> +       }
> +       #endif
> +    } "-O2 -fopt-info-all -D$macro" ]
> +
> +      # Get compiler emitted messages and delete generated file.
> +      set lines [lindex $result 0]
> +      set output [lindex $result 1]
> +      remote_file build delete $output
> +
> +      # Check pattern exits in lines, set it to zero if not found.
> +      if { [regexp $pattern $lines] } then {
> +        return 1
> +      }
> +
> +    return 0
> +}
> +
> +# Return the true if target support vectorization of 2-byte char stores
> +# with 2-byte aligned address at plain O2.
> +proc check_effective_target_vect_slp_v2qi_store { } {
> +    set pattern {add new stmt: MEM <vector\(2\) char>}
> +    set macro "TEST_V2QI"
> +    return [check_cached_effective_target vect_slp_v2qi_store {
> +       expr [check_vect_slp_aligned_store_usage $pattern $macro] }]
> +
> +}
> +
> +# Return the true if target support vectorization of 4-byte char stores
> +# with 4-byte aligned address at plain O2.
> +proc check_effective_target_vect_slp_v4qi_store { } {
> +    set pattern {add new stmt: MEM <vector\(4\) char>}
> +    set macro "TEST_V4QI"
> +    return [check_cached_effective_target vect_slp_v4qi_store {
> +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> +}
> +
> +# Return the true if target support vectorization of 8-byte char stores
> +# with 8-byte aligned address at plain O2.
> +proc check_effective_target_vect_slp_v8qi_store { } {
> +    set pattern {add new stmt: MEM <vector\(8\) char>}
> +    set macro "TEST_V8QI"
> +    return [check_cached_effective_target vect_slp_v8qi_store {
> +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> +}
> +
> +# Return the true if target support vectorization of 16-byte char stores
> +# with 16-byte aligned address at plain O2.
> +proc check_effective_target_vect_slp_v16qi_store { } {
> +    set pattern {add new stmt: MEM <vector\(16\) char>}
> +    set macro "TEST_V16QI"
> +    return [check_cached_effective_target vect_slp_v16qi_store {
> +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> +}
> +
> +# Return the true if target support vectorization of 4-byte short stores
> +# with 4-byte aligned address at plain O2.
> +proc check_effective_target_vect_slp_v2hi_store { } {
> +    set pattern {add new stmt: MEM <vector\(2\) short int>}
> +    set macro "TEST_V2HI"
> +    return [check_cached_effective_target vect_slp_v2hi_store {
> +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> +}
> +
> +# Return the true if target support vectorization of 8-byte short stores
> +# with 8-byte aligned address at plain O2.
> +proc check_effective_target_vect_slp_v4hi_store { } {
> +    set pattern {add new stmt: MEM <vector\(4\) short int>}
> +    set macro "TEST_V4HI"
> +    return [check_cached_effective_target vect_slp_v4hi_store {
> +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> +}
> +
> +# Return the true if target support vectorization of 8-byte int stores
> +# with 8-byte aligned address at plain O2.
> +proc check_effective_target_vect_slp_v2si_store { } {
> +    set pattern {add new stmt: MEM <vector\(2\) int>}
> +    set macro "TEST_V2SI"
> +    return [check_cached_effective_target vect_slp_v2si_store {
> +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> +}
> +
> +# Return the true if target support vectorization of 16-byte int stores
> +# with 16-byte aligned address at plain O2.
> +proc check_effective_target_vect_slp_v4si_store { } {
> +    set pattern {add new stmt: MEM <vector\(4\) int>}
> +    set macro "TEST_V4SI"
> +    return [check_cached_effective_target vect_slp_v4si_store {
> +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> +}
> +
>  # Return 1 if we can align stack data to the preferred vector alignment.
>
>  proc check_effective_target_vect_align_stack_vars { } {
> --
> 2.18.1
>
>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] Adjust testcase for O2 vectorization.
  2021-10-20 11:34                             ` Christophe Lyon
@ 2021-10-21  1:20                               ` Hongtao Liu
  2021-10-21  2:06                                 ` Hongtao Liu
  0 siblings, 1 reply; 29+ messages in thread
From: Hongtao Liu @ 2021-10-21  1:20 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: liuhongt, GCC Patches

On Wed, Oct 20, 2021 at 7:34 PM Christophe Lyon via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Hi,
>
>
> On Tue, Oct 19, 2021 at 11:03 AM liuhongt via Gcc-patches <
> gcc-patches@gcc.gnu.org> wrote:
>
> > updated patch:
> >   1. Add documents in doc/sourcebuild.texi (Effective-Target Keywords).
> >   2. Reduce -novec.c testcases to contain only new failed parted which
> > is caused by O2 vectorization.
> >   3. Add PR in dg-warning comment.
> >
> > As discussed in [1], this patch add xfail/target selector to those
> > testcases, also make a copy of them so that they can be tested w/o
> > vectorization.
> >
> > Newly added xfail/target selectors are used to check the vectorization
> > capability of continuous byte/double bytes storage, these scenarios
> > are exactly the part of the testcases that regressed after O2
> > vectorization.
> >
> > [1] https://gcc.gnu.org/pipermail/gcc-patches/2021-October/581456.html.
> >
> > gcc/ChangeLog
> >
> >         * doc/sourcebuild.texi (Effective-Target Keywords): Document
> >         vect_slp_v2qi_store, vect_slp_v4qi_store, vect_slp_v8qi_store,
> >         vect_slp_v16qi_store, vect_slp_v2hi_store,
> >         vect_slp_v4hi_store, vect_slp_v2si_store, vect_slp_v4si_store.
> >
> > gcc/testsuite/ChangeLog
> >
> >         PR middle-end/102722
> >         PR middle-end/102697
> >         PR middle-end/102462
> >         PR middle-end/102706
> >         PR middle-end/102744
> >         * c-c++-common/Wstringop-overflow-2.c: Adjust testcase with new
> >         xfail/target selector.
> >         * gcc.dg/Warray-bounds-51.c: Ditto.
> >         * gcc.dg/Warray-parameter-3.c: Ditto.
> >         * gcc.dg/Wstringop-overflow-14.c: Ditto.
> >         * gcc.dg/Wstringop-overflow-21.c: Ditto.
> >         * gcc.dg/Wstringop-overflow-68.c: Ditto.
> >         * gcc.dg/Wstringop-overflow-76.c: Ditto.
> >         * gcc.dg/Warray-bounds-48.c: Ditto.
> >         * gcc.dg/Wzero-length-array-bounds-2.c: Ditto.
> >
>
> Some of these adjustments cause regressions on arm / aarch64, the exact
> list depends on the target/flags.
> See
> https://people.linaro.org/~christophe.lyon/cross-validation/gcc/trunk/r12-4525-gf36240f8c835d792f788b6724e272fc0a4a4f26f/report-build-info.html
> for more on details on several combinations.
>
> Can you have a look?
Yes.
>
> Christophe
>
>         * lib/target-supports.exp (check_vect_slp_aligned_store_usage):
> >         New function.
> >         (check_effective_target_vect_slp_v2qi_store): Ditto.
> >         (check_effective_target_vect_slp_v4qi_store): Ditto.
> >         (check_effective_target_vect_slp_v8qi_store): Ditto.
> >         (check_effective_target_vect_slp_v16qi_store): Ditto.
> >         (check_effective_target_vect_slp_v2hi_store): Ditto.
> >         (check_effective_target_vect_slp_v4hi_store): Ditto.
> >         (check_effective_target_vect_slp_v2si_store): Ditto.
> >         (check_effective_target_vect_slp_v4si_store): Ditto.
> >         * c-c++-common/Wstringop-overflow-2-novec.c: New test.
> >         * gcc.dg/Warray-bounds-51-novec.c: New test.
> >         * gcc.dg/Warray-bounds-48-novec.c: New test.
> >         * gcc.dg/Warray-parameter-3-novec.c: New test.
> >         * gcc.dg/Wstringop-overflow-14-novec.c: New test.
> >         * gcc.dg/Wstringop-overflow-21-novec.c: New test.
> >         * gcc.dg/Wstringop-overflow-76-novec.c: New test.
> >         * gcc.dg/Wzero-length-array-bounds-2-novec.c: New test.
> > ---
> >  gcc/doc/sourcebuild.texi                      |  32 ++
> >  .../c-c++-common/Wstringop-overflow-2-novec.c | 126 ++++++
> >  .../c-c++-common/Wstringop-overflow-2.c       |  20 +-
> >  gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c | 364 ++++++++++++++++++
> >  gcc/testsuite/gcc.dg/Warray-bounds-48.c       |   4 +-
> >  gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c |  21 +
> >  gcc/testsuite/gcc.dg/Warray-bounds-51.c       |   2 +-
> >  .../gcc.dg/Warray-parameter-3-novec.c         |  16 +
> >  gcc/testsuite/gcc.dg/Warray-parameter-3.c     |   2 +-
> >  .../gcc.dg/Wstringop-overflow-14-novec.c      |  16 +
> >  gcc/testsuite/gcc.dg/Wstringop-overflow-14.c  |   4 +-
> >  .../gcc.dg/Wstringop-overflow-21-novec.c      |  34 ++
> >  gcc/testsuite/gcc.dg/Wstringop-overflow-21.c  |   8 +-
> >  gcc/testsuite/gcc.dg/Wstringop-overflow-68.c  |  17 +-
> >  .../gcc.dg/Wstringop-overflow-76-novec.c      |  88 +++++
> >  gcc/testsuite/gcc.dg/Wstringop-overflow-76.c  |  18 +-
> >  .../Wzero-length-array-bounds-2-novec.c       |  45 +++
> >  .../gcc.dg/Wzero-length-array-bounds-2.c      |   2 +-
> >  gcc/testsuite/lib/target-supports.exp         | 182 +++++++++
> >  19 files changed, 967 insertions(+), 34 deletions(-)
> >  create mode 100644 gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> >  create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> >  create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> >  create mode 100644 gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> >  create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> >  create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> >  create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> >  create mode 100644
> > gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
> >
> > diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
> > index b1fffd5e90f..6a165767630 100644
> > --- a/gcc/doc/sourcebuild.texi
> > +++ b/gcc/doc/sourcebuild.texi
> > @@ -1845,6 +1845,38 @@ Target supports loop vectorization with partial
> > vectors and
> >  @item vect_partial_vectors
> >  Target supports loop vectorization with partial vectors and
> >  @code{vect-partial-vector-usage} is nonzero.
> > +
> > +@item vect_slp_v2qi_store
> > +Target supports vectorization of 2-byte char stores with 2-byte aligned
> > +address at plain @option{-O2}.
> > +
> > +@item vect_slp_v4qi_store
> > +Target supports vectorization of 4-byte char stores with 4-byte aligned
> > +address at plain @option{-O2}.
> > +
> > +@item vect_slp_v8qi_store
> > +Target supports vectorization of 8-byte char stores with 8-byte aligned
> > +address at plain @option{-O2}.
> > +
> > +@item vect_slp_v16qi_store
> > +Target supports vectorization of 16-byte char stores with 16-byte aligned
> > +address at plain @option{-O2}.
> > +
> > +@item vect_slp_v2hi_store
> > +Target supports vectorization of 4-byte short stores with 4-byte aligned
> > +address at plain @option{-O2}.
> > +
> > +@item vect_slp_v4hi_store
> > +Target supports vectorization of 8-byte short stores with 8-byte aligned
> > +address at plain @option{-O2}.
> > +
> > +@item vect_slp_v2si_store
> > +Target supports vectorization of 8-byte int stores with 8-byte aligned
> > +address at plain @option{-O2}.
> > +
> > +@item vect_slp_v4si_store
> > +Target supports vectorization of 16-byte int stores with 16-byte aligned
> > +address at plain @option{-O2}.
> >  @end table
> >
> >  @subsubsection Thread Local Storage attributes
> > diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> > b/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> > new file mode 100644
> > index 00000000000..3c34ad35a5d
> > --- /dev/null
> > +++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> > @@ -0,0 +1,126 @@
> > +/* PR middle-end/91458 - inconsistent warning for writing past the end
> > +   of an array member
> > +   { dg-do compile }
> > +   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds
> > -fno-ipa-icf" } */
> > +
> > +void sink (void*);
> > +
> > +// Exercise trailing one-element array members.
> > +
> > +struct A1
> > +{
> > +  char n;
> > +  char a[1];                    // { dg-message "destination object"
> > "note" }
> > +};
> > +
> > +// Verify warning for access to a definition with an initializer that
> > doesn't
> > +// initialize the one-element array member.
> > +struct A1 a1__ = { 0 };
> > +
> > +void ga1__ (void)
> > +{
> > +  a1__.a[0] = 0;
> > +  a1__.a[1] = 1;                 // { dg-warning
> > "\\\[-Wstringop-overflow" }
> > +  a1__.a[2] = 2;                 // { dg-warning
> > "\\\[-Wstringop-overflow" }
> > +
> > +  struct A1 a = { 1 };
> > +  a.a[0] = 0;
> > +  a.a[1] = 1;                    // { dg-warning
> > "\\\[-Wstringop-overflow" }
> > +  a.a[2] = 2;                    // { dg-warning
> > "\\\[-Wstringop-overflow" }
> > +  sink (&a);
> > +}
> > +
> > +// Verify warning for access to a definition with an initializer that
> > +// initializes the one-element array member to empty.
> > +struct A1 a1_0 = { 0, { } };
> > +
> > +void ga1_0_ (void)
> > +{
> > +  a1_0.a[0] = 0;
> > +  a1_0.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +  a1_0.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +
> > +  struct A1 a = { 1, { } };
> > +  a.a[0] = 0;
> > +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +  sink (&a);
> > +}
> > +
> > +// Verify warning for access to a definition with an initializer that
> > +// initializes the one-element array member.
> > +struct A1 a1_1 = { 0, { 1 } };
> > +
> > +void ga1_1 (void)
> > +{
> > +  a1_1.a[0] = 0;
> > +  a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +  a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +
> > +  struct A1 a = { 0, { 1 } };
> > +  a.a[0] = 0;
> > +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +  sink (&a);
> > +}
> > +
> > +// Exercise interior one-element array members (verify they're not
> > +// treated as trailing.
> > +
> > +struct A1i
> > +{
> > +  char n;
> > +  char a[1];                    // { dg-message "destination object" }
> > +  char x;
> > +};
> > +
> > +// Verify warning for access to a definition with an initializer that
> > doesn't
> > +// initialize the one-element array member.
> > +struct A1i a1i__ = { 0 };
> > +
> > +void ga1i__ (void)
> > +{
> > +  a1i__.a[0] = 0;
> > +  a1i__.a[1] = 1;                // { dg-warning
> > "\\\[-Wstringop-overflow" }
> > +  a1i__.a[2] = 2;                // { dg-warning
> > "\\\[-Wstringop-overflow" }
> > +
> > +  struct A1i a = { 0 };
> > +  a.a[0] = 0;
> > +  a.a[1] = 1;                    // { dg-warning
> > "\\\[-Wstringop-overflow" }
> > +  a.a[2] = 2;                    // { dg-warning
> > "\\\[-Wstringop-overflow" }
> > +  sink (&a);
> > +}
> > +
> > +// Verify warning for access to a definition with an initializer that
> > +// initializes the one-element array member to empty.
> > +struct A1 a1i_0 = { 0, { } };
> > +
> > +void ga1i_0_ (void)
> > +{
> > +  a1i_0.a[0] = 0;
> > +  a1i_0.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +  a1i_0.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +
> > +  struct A1 a = { 0, { } };
> > +  a.a[0] = 0;
> > +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +  sink (&a);
> > +}
> > +
> > +// Verify warning for access to a definition with an initializer that
> > +// initializes the one-element array member.
> > +struct A1 a1i_1 = { 0, { 1 } };
> > +
> > +void ga1i_1 (void)
> > +{
> > +  a1i_1.a[0] = 0;
> > +  a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +  a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +
> > +  struct A1 a = { 0, { 1 } };
> > +  a.a[0] = 1;
> > +  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > +  sink (&a);
> > +}
> > diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> > b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> > index 7d29b5f48c7..ca38bda73f5 100644
> > --- a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> > +++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> > @@ -190,7 +190,7 @@ void ga1__ (void)
> >    struct A1 a = { 1 };
> >    a.a[0] = 0;
> >    a.a[1] = 1;                    // { dg-warning
> > "\\\[-Wstringop-overflow" }
> > -  a.a[2] = 2;                    // { dg-warning
> > "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> > +  a.a[2] = 2;                    // { dg-warning
> > "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store } } }
> >    sink (&a);
> >  }
> >
> > @@ -207,7 +207,7 @@ void ga1_0_ (void)
> >    struct A1 a = { 1, { } };
> >    a.a[0] = 0;
> >    a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > -  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > "" { xfail { i?86-*-* x86_64-*-* } } }
> > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > "pr102462" { xfail { vect_slp_v2qi_store } } }
> >    sink (&a);
> >  }
> >
> > @@ -221,10 +221,10 @@ void ga1_1 (void)
> >    a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow"
> > }
> >    a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow"
> > }
> >
> > -  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> > "" { target { i?86-*-* x86_64-*-* } } }
> > +  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> > "pr102706" { target { vect_slp_v4qi_store } } }
> >    a.a[0] = 0;
> > -  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > "" { xfail { i?86-*-* x86_64-*-* } } }
> > -  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > "" { xfail { i?86-*-* x86_64-*-* } } }
> > +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > "" { xfail { vect_slp_v4qi_store } } }
> > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > "" { xfail { vect_slp_v4qi_store } } }
> >    sink (&a);
> >  }
> >
> > @@ -289,7 +289,7 @@ void ga1i__ (void)
> >    struct A1i a = { 0 };
> >    a.a[0] = 0;
> >    a.a[1] = 1;                    // { dg-warning
> > "\\\[-Wstringop-overflow" }
> > -  a.a[2] = 2;                    // { dg-warning
> > "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> > +  a.a[2] = 2;                    // { dg-warning
> > "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store } } }
> >    sink (&a);
> >  }
> >
> > @@ -306,7 +306,7 @@ void ga1i_0_ (void)
> >    struct A1 a = { 0, { } };
> >    a.a[0] = 0;
> >    a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > }
> > -  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > "" { xfail { i?86-*-* x86_64-*-* } } }
> > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > "pr102462" { xfail { vect_slp_v2qi_store } } }
> >    sink (&a);
> >  }
> >
> > @@ -320,10 +320,10 @@ void ga1i_1 (void)
> >    a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow"
> > }
> >    a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow"
> > }
> >
> > -  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> > "" { target { i?86-*-* x86_64-*-* } } }
> > +  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> > "pr102462" { target { vect_slp_v4qi_store } } }
> >    a.a[0] = 1;
> > -  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > "" { xfail { i?86-*-* x86_64-*-* } } }
> > -  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow"
> > "" { xfail { i?86-*-* x86_64-*-* } } }
> > +  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > "pr102462" { xfail { vect_slp_v4qi_store } } }
> > +  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow"
> > "pr102462" { xfail { vect_slp_v4qi_store } } }
> >    sink (&a);
> >  }
> >
> > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> > b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> > new file mode 100644
> > index 00000000000..da179a2c0f5
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> > @@ -0,0 +1,364 @@
> > +/* PR middle-end/91647 - missing -Warray-bounds accessing a zero-length
> > array
> > +   of a declared object
> > +   { dg-do "compile" }
> > +   { dg-options "-O2 -Wall -fno-tree-vectorize" }
> > +   { dg-require-effective-target alloca } */
> > +
> > +typedef __INT16_TYPE__ int16_t;
> > +typedef __INT32_TYPE__ int32_t;
> > +
> > +void sink (void*);
> > +
> > +/* Exercise a true flexible member.  */
> > +
> > +struct AX
> > +{
> > +  int32_t n;
> > +  int16_t ax[];     // { dg-message "while referencing 'ax'" "member" }
> > +};
> > +
> > +static void warn_ax_local (struct AX *p)
> > +{
> > +  p->ax[0] = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->ax[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > +
> > +static void nowarn_ax_extern (struct AX *p)
> > +{
> > +  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
> > +}
> > +
> > +static void warn_ax_local_buf (struct AX *p)
> > +{
> > +  p->ax[0] = 4; p->ax[1] = 5;
> > +
> > +  p->ax[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->ax[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->ax[4] = 8;     // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > +
> > +static void warn_ax_extern_buf (struct AX *p)
> > +{
> > +  p->ax[0] = 9; p->ax[1] = 10; p->ax[2] = 11;
> > +
> > +  p->ax[3] = 12;    // { dg-warning "\\\[-Warray-bounds" }
> > +  p->ax[4] = 13;    // { dg-warning "\\\[-Warray-bounds" }
> > +  p->ax[5] = 14;    // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > +
> > +static void nowarn_ax_extern_bufx (struct AX *p)
> > +{
> > +  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
> > +}
> > +
> > +static void nowarn_ax_ref (struct AX *p)
> > +{
> > +  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
> > +}
> > +
> > +void test_ax (struct AX *p, unsigned n)
> > +{
> > +  {
> > +    struct AX sax;  // { dg-message "defined here" "struct definition" }
> > +    warn_ax_local (&sax);
> > +    sink (&sax);
> > +  }
> > +
> > +  {
> > +    extern
> > +      struct AX xsax;
> > +    nowarn_ax_extern (&xsax);
> > +    sink (&xsax);
> > +  }
> > +
> > +  {
> > +    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
> > +    char ax_buf_p2[sizeof (struct AX) + 2 * sizeof (int16_t)];
> > +    warn_ax_local_buf ((struct AX*) ax_buf_p2);
> > +    sink (ax_buf_p2);
> > +  }
> > +
> > +  {
> > +    /* Verify out-of-bounds access to the extern BUF with a known
> > +       bound is diagnosed.  */
> > +    extern char ax_buf_p3[sizeof (struct AX) + 3 * sizeof (int16_t)];
> > +    warn_ax_extern_buf ((struct AX*) ax_buf_p3);
> > +    sink (ax_buf_p3);
> > +  }
> > +
> > +  {
> > +    /* Verify that accesses to BUFX with an unknown bound are not
> > +       diagnosed.  */
> > +    extern char bufx[];
> > +    nowarn_ax_extern_bufx ((struct AX*) bufx);
> > +    sink (bufx);
> > +  }
> > +
> > +  {
> > +    /* Verify that accesses to BUFN with a runtime bound are not
> > +       diagnosed.  */
> > +    char bufn[n];
> > +    nowarn_ax_extern_bufx ((struct AX*) bufn);
> > +    sink (bufn);
> > +  }
> > +
> > +  nowarn_ax_ref (p);
> > +}
> > +
> > +
> > +/* Exercise a zero-length trailing member array.  It's the same as above
> > +   except that extern declarations with no definitions are considered to
> > +   have zero elements (they can't be initialized to have any).  */
> > +
> > +struct A0
> > +{
> > +  int32_t n;
> > +  int16_t a0[0];    // { dg-message "while referencing 'a0'" "member" }
> > +};
> > +
> > +static void warn_a0_local (struct A0 *p)
> > +{
> > +  p->a0[0] = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->a0[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > +
> > +static void warn_a0_extern (struct A0 *p)
> > +{
> > +  p->a0[0] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->a0[1] = 3;     // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > +
> > +static void warn_a0_local_buf (struct A0 *p)
> > +{
> > +  p->a0[0] = 4; p->a0[1] = 5;
> > +
> > +  p->a0[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->a0[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->a0[4] = 8;     // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > +
> > +static void warn_a0_extern_buf (struct A0 *p)
> > +{
> > +  p->a0[0] = 9; p->a0[1] = 10; p->a0[2] = 11;
> > +
> > +  p->a0[3] = 12;    // { dg-warning "\\\[-Warray-bounds" }
> > +  p->a0[4] = 13;    // { dg-warning "\\\[-Warray-bounds" }
> > +  p->a0[5] = 14;    // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > +
> > +static void nowarn_a0_extern_bufx (struct A0 *p)
> > +{
> > +  p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
> > +}
> > +
> > +static void nowarn_a0_ref (struct A0 *p)
> > +{
> > +  p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
> > +}
> > +
> > +void test_a0 (struct A0 *p, unsigned n)
> > +{
> > +  {
> > +    struct A0 sa0;  // { dg-message "defined here" "struct definition" }
> > +    warn_a0_local (&sa0);
> > +    sink (&sa0);
> > +  }
> > +
> > +  {
> > +    extern
> > +      struct A0 xsa0;  // { dg-message "defined here" "struct definition"
> > }
> > +    warn_a0_extern (&xsa0);
> > +    sink (&xsa0);
> > +  }
> > +
> > +  {
> > +    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
> > +    char a0_buf_p2[sizeof (struct A0) + 2 * sizeof (int16_t)];
> > +    warn_a0_local_buf ((struct A0*) a0_buf_p2);
> > +    sink (a0_buf_p2);
> > +  }
> > +
> > +  {
> > +    /* Verify out-of-bounds access to the extern BUF with a known
> > +       bound is diagnosed.  */
> > +    extern char a0_buf_p3[sizeof (struct A0) + 3 * sizeof (int16_t)];
> > +    warn_a0_extern_buf ((struct A0*) a0_buf_p3);
> > +    sink (a0_buf_p3);
> > +  }
> > +
> > +  {
> > +    /* Verify that accesses to BUFX with an unknown bound are not
> > +       diagnosed.  */
> > +    extern char bufx[];
> > +    nowarn_a0_extern_bufx ((struct A0*) bufx);
> > +    sink (bufx);
> > +  }
> > +
> > +  {
> > +    /* Verify that accesses to BUFN with a runtime bound are not
> > +       diagnosed.  */
> > +    char bufn[n];
> > +    nowarn_a0_extern_bufx ((struct A0*) bufn);
> > +    sink (bufn);
> > +  }
> > +
> > +  nowarn_a0_ref (p);
> > +}
> > +
> > +
> > +/* Exercise a one-element trailing member array.  It's the same as above
> > +   except that it has exactly one element.  */
> > +
> > +struct A1
> > +{
> > +  int32_t n;
> > +  int16_t a1[1];    // { dg-message "while referencing 'a1'" }
> > +};
> > +
> > +static void warn_a1_local_noinit (struct A1 *p)
> > +{
> > +  p->a1[0] = 0;
> > +  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > +
> > +static void warn_a1_extern (struct A1 *p)
> > +{
> > +  p->a1[0] = 0;
> > +  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > +
> > +static void warn_a1_init (struct A1 *p)
> > +{
> > +  p->a1[0] = 0;
> > +  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > +
> > +static void warn_a1_local_buf (struct A1 *p)
> > +{
> > +  p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3;
> > +
> > +  p->a1[4] = 4;     // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > +
> > +static void warn_a1_extern_buf (struct A1 *p)
> > +{
> > +  p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3; p->a1[4] = 4;
> > +
> > +  p->a1[5] = 5;     // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > +
> > +static void nowarn_a1_extern_bufx (struct A1 *p)
> > +{
> > +  p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
> > +}
> > +
> > +static void nowarn_a1_ref (struct A1 *p)
> > +{
> > +  p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
> > +}
> > +
> > +void test_a1 (struct A1 *p, unsigned n)
> > +{
> > +  {
> > +    struct A1 a1;
> > +    warn_a1_local_noinit (&a1);
> > +    sink (&a1);
> > +  }
> > +
> > +  {
> > +    extern struct A1 a1x;
> > +    warn_a1_extern (&a1x);
> > +    sink (&a1x);
> > +}
> > +  {
> > +    struct A1 a1 = { 0, { 1 } };
> > +    warn_a1_init (&a1);
> > +    sink (&a1);
> > +  }
> > +
> > +  {
> > +    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
> > +    char buf_p2[sizeof (struct A1) + 2 * sizeof (int16_t)];
> > +    warn_a1_local_buf ((struct A1*) buf_p2);
> > +    sink (buf_p2);
> > +  }
> > +
> > +  {
> > +    /* Verify out-of-bounds access to the extern BUF with a known
> > +       bound is diagnosed.  */
> > +    extern char a1_buf_p3[sizeof (struct A1) + 3 * sizeof (int16_t)];
> > +    warn_a1_extern_buf ((struct A1*) a1_buf_p3);
> > +    sink (a1_buf_p3);
> > +  }
> > +
> > +  {
> > +    /* Verify that accesses to BUFX with an unknown bound are not
> > +       diagnosed.  */
> > +    extern char bufx[];
> > +    nowarn_a1_extern_bufx ((struct A1*) bufx);
> > +    sink (bufx);
> > +  }
> > +
> > +  {
> > +    /* Verify that accesses to BUFN with a runtime bound are not
> > +       diagnosed.  */
> > +    char bufn[n];
> > +    nowarn_a1_extern_bufx ((struct A1*) bufn);
> > +    sink (bufn);
> > +  }
> > +
> > +  nowarn_a1_ref (p);
> > +}
> > +
> > +
> > +/* Exercise a two-element trailing member array.  It's treated
> > +   the same as an interior array member.  */
> > +
> > +struct A2
> > +{
> > +  int32_t n;
> > +  int16_t a2[2];    // { dg-message "while referencing 'a2'" }
> > +};
> > +
> > +static void warn_a2_noinit (struct A2 *p)
> > +{
> > +  p->a2[0] = 0; p->a2[1] = 1;
> > +
> > +  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > +
> > +static void warn_a2_init (struct A2 *p)
> > +{
> > +  p->a2[0] = 0; p->a2[1] = 1;
> > +
> > +  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->a2[9] = 9;     // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > +
> > +static void warn_a2_ref (struct A2 *p)
> > +{
> > +  p->a2[0] = 0; p->a2[1] = 1;
> > +
> > +  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->a2[9] = 9;     // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > +
> > +void test_a2 (struct A2 *p)
> > +{
> > +  {
> > +    struct A2 a2;
> > +    warn_a2_noinit (&a2);
> > +    sink (&a2);
> > +  }
> > +
> > +  {
> > +    struct A2 a2 = { 0, { 1, 2 } };
> > +    warn_a2_init (&a2);
> > +    sink (&a2);
> > +  }
> > +
> > +  warn_a2_ref (p);
> > +}
> > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> > b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> > index 13373d1e99e..19b7634c063 100644
> > --- a/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> > @@ -30,7 +30,7 @@ static void nowarn_ax_extern (struct AX *p)
> >
> >  static void warn_ax_local_buf (struct AX *p)
> >  {
> > -  p->ax[0] = 4; p->ax[1] = 5;
> > +  p->ax[0] = 4; p->ax[1] = 5;  // { dg-warning "\\\[-Wstringop-overflow"
> > "pr102706" { target { vect_slp_v2hi_store &&  { ! vect_slp_v4hi_store } } }
> > }
> >
> >    p->ax[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> >    p->ax[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> > @@ -130,7 +130,7 @@ static void warn_a0_extern (struct A0 *p)
> >
> >  static void warn_a0_local_buf (struct A0 *p)
> >  {
> > -  p->a0[0] = 4; p->a0[1] = 5;
> > +  p->a0[0] = 4; p->a0[1] = 5;  // { dg-warning "\\\[-Wstringop-overflow"
> > "pr102706" { target { vect_slp_v2hi_store && { ! vect_slp_v4hi_store } } } }
> >
> >    p->a0[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> >    p->a0[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> > b/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> > new file mode 100644
> > index 00000000000..ef8056d9b7f
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> > @@ -0,0 +1,21 @@
> > +/* PR middle-end/92333 - missing variable name referencing VLA in warnings
> > +   PR middle-end/82608 - missing -Warray-bounds on an out-of-bounds VLA
> > index
> > +   { dg-do compile }
> > +   { dg-options "-O2 -Wall -fno-tree-vectorize" }  */
> > +
> > +void sink (void*);
> > +
> > +void test_struct_char_vla_location (void)
> > +{
> > +  unsigned nelts = 7;
> > +
> > +  struct {
> > +    char cvla[nelts]; // { dg-message "declared here|while referencing" }
> > +  } s;
> > +
> > +  s.cvla[0] = __LINE__;
> > +  s.cvla[nelts - 1] = 0;
> > +  s.cvla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
> > +
> > +  sink (&s);
> > +}
> > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> > b/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> > index de60d87ab95..8b589f38191 100644
> > --- a/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> > @@ -39,7 +39,7 @@ void test_struct_char_vla_location (void)
> >    } s;
> >
> >    s.cvla[0] = __LINE__;
> > -  s.cvla[nelts - 1] = 0; // { dg-warning "\\\[-Wstringop-overflow" "" {
> > target { i?86-*-* x86_64-*-* } } }
> > +  s.cvla[nelts - 1] = 0; // { dg-warning "\\\[-Wstringop-overflow"
> > "pr102706" { target { vect_slp_v2qi_store } } }
> >    s.cvla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
> >
> >    sink (&s);
> > diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> > b/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> > new file mode 100644
> > index 00000000000..5089d555392
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> > @@ -0,0 +1,16 @@
> > +/* PR c/50584 - No warning for passing small array to C99 static array
> > +   declarator
> > +   { dg-do compile }
> > +   { dg-options "-Wall -Warray-parameter=1" } */
> > +
> > +/* Also verify that -Warray-bounds doesn't trigger for ordinary array
> > +   parameters...  */
> > +#pragma GCC optimize ("2,no-tree-vectorize")
> > +
> > +/* ...but does for static arrays.  */
> > +__attribute__ ((noipa)) void
> > +gcas3 (char a[static 3])
> > +{
> > +  a[0] = 0; a[1] = 1; a[2] = 2;
> > +  a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
> > +}
> > diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> > b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> > index e8a269c85c6..b6ed8daf51c 100644
> > --- a/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> > +++ b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> > @@ -77,7 +77,7 @@ gia3 (int a[3])
> >  __attribute__ ((noipa)) void
> >  gcas3 (char a[static 3])
> >  {
> > -  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow"
> > "" { target { i?86-*-* x86_64-*-* } } }
> > +  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow"
> > "pr102706" { target { vect_slp_v4qi_store } } }
> >    a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
> >  }
> >
> > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> > b/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> > new file mode 100644
> > index 00000000000..de39eaaeb95
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> > @@ -0,0 +1,16 @@
> > +/* Test to verify that past-the-end multibyte writes via lvalues of wider
> > +   types than char are diagnosed.
> > +   { dg-do compile }
> > +   { dg-require-effective-target int32plus }
> > +   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds" }  */
> > +
> > +typedef __INT16_TYPE__  int16_t;
> > +
> > +char a4[4], a8[8], a16[16];
> > +
> > +void test_int16 (void)
> > +{
> > +  char *p = a4 + 1;
> > +  *(int16_t*)p = 0;
> > +  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a
> > region of size 1" }
> > +}
> > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> > b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> > index 7683084e46e..c4a3f05d883 100644
> > --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> > @@ -36,8 +36,8 @@ void test_memcpy_cond (int i)
> >  void test_int16 (void)
> >  {
> >    char *p = a4 + 1;
> > -  *(int16_t*)p = 0;    // { dg-warning "writing 4 bytes into a region of
> > size 3" "" { target { i?86-*-* x86_64-*-* } } }
> > -  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a
> > region of size 1" "" { xfail { i?86-*-* x86_64-*-* } } }
> > +  *(int16_t*)p = 0;    // { dg-warning "writing 4 bytes into a region of
> > size 3" "pr102706" { target { vect_slp_v2hi_store } } }
> > +  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a
> > region of size 1" "pr102706" { xfail { vect_slp_v2hi_store } } }
> >  }
> >
> >
> > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> > b/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> > new file mode 100644
> > index 00000000000..6f83548e902
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> > @@ -0,0 +1,34 @@
> > +/* PR middle-end/92312 - bogus -Wstringop-overflow storing into a trailing
> > +   array backed by larger buffer
> > +   { dg-do compile }
> > +   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds" } */
> > +
> > +struct S0 { char a, b[0]; };
> > +
> > +void sink (void*);
> > +
> > +void test_store_zero_length (int i)
> > +{
> > +  char a[3];
> > +  struct S0 *p = (struct S0*)a;
> > +  p->a = 0;
> > +  p->b[0] = 0;
> > +  p->b[1] = 1;                      // { dg-bogus
> > "\\\[-Wstringop-overflow" }
> > +  p->b[2] = 2;                      // { dg-warning
> > "\\\[-Wstringop-overflow" }
> > +  p->b[i] = 2;
> > +  sink (p);
> > +}
> > +
> > +struct Sx { char a, b[]; };
> > +
> > +void test_store_flexarray (int i)
> > +{
> > +  char a[3];
> > +  struct Sx *p = (struct Sx*)a;
> > +  p->a = 0;
> > +  p->b[0] = 0;
> > +  p->b[1] = 1;                      // { dg-bogus
> > "\\\[-Wstringop-overflow" }
> > +  p->b[2] = 1;                      // { dg-warning
> > "\\\[-Wstringop-overflow" }
> > +  p->b[i] = 2;
> > +  sink (p);
> > +}
> > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> > b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> > index d88bde9c740..3fccfc9a798 100644
> > --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> > @@ -23,10 +23,10 @@ void test_store_zero_length (int i)
> >  {
> >    char a[3];
> >    struct S0 *p = (struct S0*)a;
> > -  p->a = 0;                         // { dg-warning
> > "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> > +  p->a = 0;                         // { dg-warning
> > "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v4qi_store } } }
> >    p->b[0] = 0;
> >    p->b[1] = 1;                      // { dg-bogus
> > "\\\[-Wstringop-overflow" }
> > -  p->b[2] = 2;                      // { dg-warning
> > "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> > +  p->b[2] = 2;                      // { dg-warning
> > "\\\[-Wstringop-overflow" "pr102706" { xfail { vect_slp_v4qi_store } } }
> >    p->b[i] = 2;
> >    sink (p);
> >  }
> > @@ -50,10 +50,10 @@ void test_store_flexarray (int i)
> >  {
> >    char a[3];
> >    struct Sx *p = (struct Sx*)a;
> > -  p->a = 0;                         // { dg-warning
> > "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> > +  p->a = 0;                         // { dg-warning
> > "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v4qi_store } } }
> >    p->b[0] = 0;
> >    p->b[1] = 1;                      // { dg-bogus
> > "\\\[-Wstringop-overflow" }
> > -  p->b[2] = 1;                      // { dg-warning
> > "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> > +  p->b[2] = 1;                      // { dg-warning
> > "\\\[-Wstringop-overflow" "pr102706" { xfail { vect_slp_v4qi_store } } }
> >    p->b[i] = 2;
> >    sink (p);
> >  }
> > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> > b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> > index 09df0004991..04e91afb8bc 100644
> > --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> > @@ -58,11 +58,18 @@ void warn_comp_lit_zero (void)
> >  void warn_comp_lit (void)
> >  {
> >    *(AC2*)a1 = Ac2;      // { dg-warning "writing 2 bytes into a region of
> > size 1" "pr101475" { xfail *-*-* } }
> > -  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> > size 2" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> > -  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> > size 3" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> > -  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> > size 4" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> > -  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> > size 7" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> > -  *(AC16*)a15 = Ac16;   // { dg-warning "writing 16 bytes into a region
> > of size 15" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> > +  // After vectorization, below codes are optimized to
> > +  // MEM <vector(4) char> [(char *)&a2] = { 0, 1, 2, 3 };
> > +  // MEM <vector(4) char> [(char *)&a3] = { 0, 1, 2, 3 };
> > +  // MEM <vector(8) char> [(char *)&a4] = { 0, 1, 2, 3, 4, 5, 6, 7 };
> > +  // MEM <vector(8) char> [(char *)&a7] = { 0, 1, 2, 3, 4, 5, 6, 7 };
> > +  // MEM <vector(16) char> [(char *)&a15] = { 0, 1, 2, 3, 4, 5, 6, 7, 8,
> > 9, 10, 11, 12, 13, 14, 15 };
> > +  // and warning should be expected, refer to PR102722.
> > +  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> > size 2" "pr101475" { xfail { ! { vect_slp_v4qi_store } } } }
> > +  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> > size 3" "pr101475" { xfail { ! { vect_slp_v4qi_store } } } }
> > +  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> > size 4" "pr101475" { xfail { ! { vect_slp_v8qi_store } } } }
> > +  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> > size 7" "pr101475" { xfail { ! { vect_slp_v8qi_store } } } }
> > +  *(AC16*)a15 = Ac16;   // { dg-warning "writing 16 bytes into a region
> > of size 15" "pr101475" { xfail { ! { vect_slp_v16qi_store } } } }
> >  }
> >
> >  void warn_aggr_decl (void)
> > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> > b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> > new file mode 100644
> > index 00000000000..71c643b62fb
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> > @@ -0,0 +1,88 @@
> > +/* Verify warnings and notes for MAX_EXPRs involving either pointers
> > +   to distinct objects or one to a known object and the other to
> > +   an unknown one.  Unlike for the same object, for unrelated objects
> > +   the expected warnings and notes are the same as for MIN_EXPR: when
> > +   the order of the objects in the address space cannot be determined
> > +   the larger of them is assumed to be used.  (This is different for
> > +   distinct struct members where the order is given.)
> > +   The relational expressions are strictly invalid but that should be
> > +   diagnosed by a separate warning.
> > +   { dg-do compile }
> > +   { dg-options "-O2 -Wno-array-bounds -fno-tree-vectorize" } */
> > +
> > +#define MAX(p, q) ((p) > (q) ? (p) : (q))
> > +
> > +/* Verify that even for MAX_EXPR and like for MIN_EXPR, the note points
> > +   to the larger of the two objects and mentions the offset into it
> > +   (although the offset might be better included in the warning).  */
> > +extern char a3[3];
> > +extern char a5[5];  // { dg-message "at offset 5 into destination object
> > 'a5' of size 5" "note" }
> > +
> > +void max_a3_a5 (int i)
> > +{
> > +  char *p = a3 + i;
> > +  char *q = a5 + i;
> > +
> > +  /* The relational expression below is invalid and should be diagnosed
> > +     by its own warning independently of -Wstringop-overflow.  */
> > +  char *d = MAX (p, q);
> > +
> > +  d[2] = 0;
> > +  d[3] = 0;
> > +  d[4] = 0;
> > +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > 0" }
> > +}
> > +
> > +
> > +// Same as above but with the larger array as the first MAX_EXPR operand.
> > +extern char b4[4];
> > +extern char b6[6];  // { dg-message "at offset 6 into destination object
> > 'b6' of size 6" "note" }
> > +
> > +void max_b6_b4 (int i)
> > +{
> > +  char *p = b6 + i;
> > +  char *q = b4 + i;
> > +  char *d = MAX (p, q);
> > +
> > +  d[3] = 0;
> > +  d[4] = 0;
> > +  d[5] = 0;
> > +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > 0" }
> > +}
> > +
> > +struct A3_5
> > +{
> > +  char a3[3];  // { dg-message "at offset 3 into destination object 'a3'
> > of size 3" "pr??????" { xfail *-*-* } }
> > +  char a5[5];  // { dg-message "at offset 5 into destination object 'a5'
> > of size 5" "note" }
> > +};
> > +
> > +void max_A3_A5 (int i, struct A3_5 *pa3_5)
> > +{
> > +  char *p = pa3_5->a3 + i;
> > +  char *q = pa3_5->a5 + i;
> > +
> > +  char *d = MAX (p, q);
> > +  d[2] = 0;
> > +  d[3] = 0;         // { dg-warning "writing 1 byte into a region of size
> > 0" "pr??????" { xfail *-*-* } }
> > +  d[4] = 0;
> > +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > 0" }
> > +}
> > +
> > +
> > +struct B4_B6
> > +{
> > +  char b4[4];
> > +  char b6[6];       // { dg-message "at offset 6 into destination object
> > 'b6' of size 6" "note" }
> > +};
> > +
> > +void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
> > +{
> > +  char *p = pb4_b6->b6 + i;
> > +  char *q = pb4_b6->b4 + i;
> > +  char *d = MAX (p, q);
> > +
> > +  d[3] = 0;
> > +  d[4] = 0;
> > +  d[5] = 0;
> > +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > 0" }
> > +}
> > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> > b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> > index 0c7b53ccc0b..52467267a04 100644
> > --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> > @@ -27,10 +27,10 @@ void max_a3_a5 (int i)
> >       by its own warning independently of -Wstringop-overflow.  */
> >    char *d = MAX (p, q);
> >
> > -  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of
> > size 3" "" { target { i?86-*-* x86_64-*-* } } }
> > +  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of
> > size 3" "pr102706" { target { vect_slp_v4qi_store } } }
> >    d[3] = 0;
> >    d[4] = 0;
> > -  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> > +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > 0" "pr102706" { xfail { vect_slp_v4qi_store } } }
> >  }
> >
> >
> > @@ -44,10 +44,10 @@ void max_b6_b4 (int i)
> >    char *q = b4 + i;
> >    char *d = MAX (p, q);
> >
> > -  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of
> > size 3" "" { target { i?86-*-* x86_64-*-* } } }
> > +  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of
> > size 3" "pr102706" { target { vect_slp_v4qi_store } } }
> >    d[4] = 0;
> >    d[5] = 0;
> > -  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> > +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > 0" "pr102706" { xfail { vect_slp_v4qi_store } } }
> >  }
> >
> >
> > @@ -82,7 +82,8 @@ void max_d8_p (char *q, int i)
> >  struct A3_5
> >  {
> >    char a3[3];  // { dg-message "at offset 3 into destination object 'a3'
> > of size 3" "pr??????" { xfail *-*-* } }
> > -  char a5[5];  // { dg-message "at offset 5 into destination object 'a5'
> > of size 5" "note" { xfail { i?86-*-* x86_64-*-* } } }
> > +  // refer to pr102697 for xfail
> > +  char a5[5];  // { dg-message "at offset 5 into destination object 'a5'
> > of size 5" "note" { xfail { vect_slp_v4qi_store } } }
> >  };
> >
> >  void max_A3_A5 (int i, struct A3_5 *pa3_5)
> > @@ -95,14 +96,15 @@ void max_A3_A5 (int i, struct A3_5 *pa3_5)
> >    d[2] = 0;
> >    d[3] = 0;         // { dg-warning "writing 1 byte into a region of size
> > 0" "pr??????" { xfail *-*-* } }
> >    d[4] = 0;
> > -  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> > +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > 0" "pr102697" { xfail { vect_slp_v4qi_store } } }
> >  }
> >
> >
> >  struct B4_B6
> >  {
> >    char b4[4];
> > -  char b6[6];       // { dg-message "at offset
> > \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6"
> > "note" { xfail { i?86-*-* x86_64-*-* } } }
> > +  // refer to pr102697 for xfail
> > +  char b6[6];       // { dg-message "at offset
> > \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6"
> > "note" { xfail { vect_slp_v4qi_store } } }
> >  };
> >
> >  void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
> > @@ -114,7 +116,7 @@ void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
> >    d[3] = 0;
> >    d[4] = 0;
> >    d[5] = 0;
> > -  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> > +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > 0" "pr102697" { xfail { vect_slp_v4qi_store } } }
> >  }
> >
> >
> > diff --git a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
> > b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
> > new file mode 100644
> > index 00000000000..8e023b7cfa7
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
> > @@ -0,0 +1,45 @@
> > +/* Test to verify that -Wzero-length-bounds and not -Warray-bounds is
> > +   issued for accesses to interior zero-length array members that are
> > +   within the bounds of the enclosing struct.
> > +   { dg-do compile }
> > +   { dg-options "-O2 -Wall -fno-tree-vectorize" } */
> > +
> > +void sink (void*);
> > +
> > +struct A { int i; };
> > +struct B { int j; struct A a[0]; };
> > +
> > +struct C
> > +{
> > +  struct B b1;
> > +  struct B b2;
> > +};
> > +
> > +char cbuf1[1 * sizeof (struct C)];
> > +char cbuf2[2 * sizeof (struct C)] = { };
> > +
> > +void test_C_global_buf (void)
> > +{
> > +  struct C *p = (struct C*)&cbuf1;
> > +
> > +  p->b1.a[-1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->b1.a[ 0].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
> > +  p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > +  sink (p);
> > +
> > +  p->b2.a[ 0].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->b2.a[ 1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > +  sink (p);
> > +
> > +  p = (struct C*)&cbuf2;
> > +  p->b1.a[-1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->b1.a[ 0].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
> > +  p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
> > +  sink (p);
> > +
> > +  p->b2.a[ 0].i = 0;
> > +  p->b2.a[ 1].i = 0;
> > +  p->b2.a[ 2].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > +  p->b2.a[ 3].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > +  sink (p);
> > +}
> > diff --git a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> > b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> > index 841b2bfa122..b2321495afc 100644
> > --- a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> > +++ b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> > @@ -87,7 +87,7 @@ void test_C_global_buf (void)
> >    p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
> >    sink (p);
> >
> > -  p->b2.a[ 0].i = 0;
> > +  p->b2.a[ 0].i = 0;    // { dg-warning "\\\[-Wstringop-overflow"
> > "pr102706" { target { vect_slp_v2si_store &&  { ! vect_slp_v4si_store } } }
> > }
> >    p->b2.a[ 1].i = 0;
> >    p->b2.a[ 2].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> >    p->b2.a[ 3].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > diff --git a/gcc/testsuite/lib/target-supports.exp
> > b/gcc/testsuite/lib/target-supports.exp
> > index 9ebca7ac007..1c8b1ebb86e 100644
> > --- a/gcc/testsuite/lib/target-supports.exp
> > +++ b/gcc/testsuite/lib/target-supports.exp
> > @@ -7580,6 +7580,188 @@ proc
> > check_effective_target_vect_element_align_preferred { } {
> >                    && [check_effective_target_vect_variable_length] }]
> >  }
> >
> > +# Return true if vectorization of v2qi/v4qi/v8qi/v16qi/v2hi store is
> > enabed.
> > +# Return zero if the desirable pattern isn't found.
> > +# It's used by Warray-bounds/Wstringop-overflow testcases which are
> > +# regressed by O2 vectorization, refer to PR102697/PR102462/PR102706
> > +proc check_vect_slp_aligned_store_usage { pattern macro } {
> > +    global tool
> > +
> > +    set result [check_compile slp_aligned_store_usage assembly {
> > +       char a[16] __attribute__ ((aligned (16)));
> > +       short b[4] __attribute__((aligned(8)));
> > +       int c[4] __attribute__((aligned(16)));
> > +       #ifdef TEST_V8QI
> > +       void
> > +       foo ()
> > +       {
> > +           a[0] = 0;
> > +           a[1] = 1;
> > +           a[2] = 2;
> > +           a[3] = 3;
> > +           a[4] = 4;
> > +           a[5] = 5;
> > +           a[6] = 6;
> > +           a[7] = 7;
> > +       }
> > +       #elif TEST_V16QI
> > +       void
> > +       foo1 ()
> > +       {
> > +           a[0] = 0;
> > +           a[1] = 1;
> > +           a[2] = 2;
> > +           a[3] = 3;
> > +           a[4] = 4;
> > +           a[5] = 5;
> > +           a[6] = 6;
> > +           a[7] = 7;
> > +           a[8] = 8;
> > +           a[9] = 9;
> > +           a[10] = 10;
> > +           a[11] = 11;
> > +           a[12] = 12;
> > +           a[13] = 13;
> > +           a[14] = 14;
> > +           a[15] = 15;
> > +       }
> > +       #elif TEST_V4QI
> > +       void
> > +       foo2 ()
> > +       {
> > +           a[0] = 0;
> > +           a[1] = 1;
> > +           a[2] = 2;
> > +           a[3] = 3;
> > +       }
> > +       #elif TEST_V2QI
> > +       void
> > +       foo3 ()
> > +       {
> > +           a[0] = 0;
> > +           a[1] = 1;
> > +       }
> > +       #elif TEST_V2HI
> > +       void
> > +       foo4 ()
> > +       {
> > +           b[0] = 0;
> > +           b[1] = 1;
> > +       }
> > +       #elif TEST_V4HI
> > +       void
> > +       foo5 ()
> > +       {
> > +           b[0] = 0;
> > +           b[1] = 1;
> > +           b[2] = 2;
> > +           b[3] = 3;
> > +       }
> > +       #elif TEST_V2SI
> > +       void
> > +       foo6 ()
> > +       {
> > +           c[0] = 0;
> > +           c[1] = 1;
> > +       }
> > +       #elif TEST_V4SI
> > +       void
> > +       foo7 ()
> > +       {
> > +           c[0] = 0;
> > +           c[1] = 1;
> > +           c[2] = 2;
> > +           c[3] = 3;
> > +       }
> > +       #endif
> > +    } "-O2 -fopt-info-all -D$macro" ]
> > +
> > +      # Get compiler emitted messages and delete generated file.
> > +      set lines [lindex $result 0]
> > +      set output [lindex $result 1]
> > +      remote_file build delete $output
> > +
> > +      # Check pattern exits in lines, set it to zero if not found.
> > +      if { [regexp $pattern $lines] } then {
> > +        return 1
> > +      }
> > +
> > +    return 0
> > +}
> > +
> > +# Return the true if target support vectorization of 2-byte char stores
> > +# with 2-byte aligned address at plain O2.
> > +proc check_effective_target_vect_slp_v2qi_store { } {
> > +    set pattern {add new stmt: MEM <vector\(2\) char>}
> > +    set macro "TEST_V2QI"
> > +    return [check_cached_effective_target vect_slp_v2qi_store {
> > +       expr [check_vect_slp_aligned_store_usage $pattern $macro] }]
> > +
> > +}
> > +
> > +# Return the true if target support vectorization of 4-byte char stores
> > +# with 4-byte aligned address at plain O2.
> > +proc check_effective_target_vect_slp_v4qi_store { } {
> > +    set pattern {add new stmt: MEM <vector\(4\) char>}
> > +    set macro "TEST_V4QI"
> > +    return [check_cached_effective_target vect_slp_v4qi_store {
> > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > +}
> > +
> > +# Return the true if target support vectorization of 8-byte char stores
> > +# with 8-byte aligned address at plain O2.
> > +proc check_effective_target_vect_slp_v8qi_store { } {
> > +    set pattern {add new stmt: MEM <vector\(8\) char>}
> > +    set macro "TEST_V8QI"
> > +    return [check_cached_effective_target vect_slp_v8qi_store {
> > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > +}
> > +
> > +# Return the true if target support vectorization of 16-byte char stores
> > +# with 16-byte aligned address at plain O2.
> > +proc check_effective_target_vect_slp_v16qi_store { } {
> > +    set pattern {add new stmt: MEM <vector\(16\) char>}
> > +    set macro "TEST_V16QI"
> > +    return [check_cached_effective_target vect_slp_v16qi_store {
> > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > +}
> > +
> > +# Return the true if target support vectorization of 4-byte short stores
> > +# with 4-byte aligned address at plain O2.
> > +proc check_effective_target_vect_slp_v2hi_store { } {
> > +    set pattern {add new stmt: MEM <vector\(2\) short int>}
> > +    set macro "TEST_V2HI"
> > +    return [check_cached_effective_target vect_slp_v2hi_store {
> > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > +}
> > +
> > +# Return the true if target support vectorization of 8-byte short stores
> > +# with 8-byte aligned address at plain O2.
> > +proc check_effective_target_vect_slp_v4hi_store { } {
> > +    set pattern {add new stmt: MEM <vector\(4\) short int>}
> > +    set macro "TEST_V4HI"
> > +    return [check_cached_effective_target vect_slp_v4hi_store {
> > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > +}
> > +
> > +# Return the true if target support vectorization of 8-byte int stores
> > +# with 8-byte aligned address at plain O2.
> > +proc check_effective_target_vect_slp_v2si_store { } {
> > +    set pattern {add new stmt: MEM <vector\(2\) int>}
> > +    set macro "TEST_V2SI"
> > +    return [check_cached_effective_target vect_slp_v2si_store {
> > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > +}
> > +
> > +# Return the true if target support vectorization of 16-byte int stores
> > +# with 16-byte aligned address at plain O2.
> > +proc check_effective_target_vect_slp_v4si_store { } {
> > +    set pattern {add new stmt: MEM <vector\(4\) int>}
> > +    set macro "TEST_V4SI"
> > +    return [check_cached_effective_target vect_slp_v4si_store {
> > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > +}
> > +
> >  # Return 1 if we can align stack data to the preferred vector alignment.
> >
> >  proc check_effective_target_vect_align_stack_vars { } {
> > --
> > 2.18.1
> >
> >



-- 
BR,
Hongtao

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] Adjust testcase for O2 vectorization.
  2021-10-21  1:20                               ` Hongtao Liu
@ 2021-10-21  2:06                                 ` Hongtao Liu
  2021-10-21  2:07                                   ` Hongtao Liu
  0 siblings, 1 reply; 29+ messages in thread
From: Hongtao Liu @ 2021-10-21  2:06 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: liuhongt, GCC Patches

On Thu, Oct 21, 2021 at 9:20 AM Hongtao Liu <crazylht@gmail.com> wrote:
>
> On Wed, Oct 20, 2021 at 7:34 PM Christophe Lyon via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
> >
> > Hi,
> >
> >
> > On Tue, Oct 19, 2021 at 11:03 AM liuhongt via Gcc-patches <
> > gcc-patches@gcc.gnu.org> wrote:
> >
> > > updated patch:
> > >   1. Add documents in doc/sourcebuild.texi (Effective-Target Keywords).
> > >   2. Reduce -novec.c testcases to contain only new failed parted which
> > > is caused by O2 vectorization.
> > >   3. Add PR in dg-warning comment.
> > >
> > > As discussed in [1], this patch add xfail/target selector to those
> > > testcases, also make a copy of them so that they can be tested w/o
> > > vectorization.
> > >
> > > Newly added xfail/target selectors are used to check the vectorization
> > > capability of continuous byte/double bytes storage, these scenarios
> > > are exactly the part of the testcases that regressed after O2
> > > vectorization.
> > >
> > > [1] https://gcc.gnu.org/pipermail/gcc-patches/2021-October/581456.html.
> > >
> > > gcc/ChangeLog
> > >
> > >         * doc/sourcebuild.texi (Effective-Target Keywords): Document
> > >         vect_slp_v2qi_store, vect_slp_v4qi_store, vect_slp_v8qi_store,
> > >         vect_slp_v16qi_store, vect_slp_v2hi_store,
> > >         vect_slp_v4hi_store, vect_slp_v2si_store, vect_slp_v4si_store.
> > >
> > > gcc/testsuite/ChangeLog
> > >
> > >         PR middle-end/102722
> > >         PR middle-end/102697
> > >         PR middle-end/102462
> > >         PR middle-end/102706
> > >         PR middle-end/102744
> > >         * c-c++-common/Wstringop-overflow-2.c: Adjust testcase with new
> > >         xfail/target selector.
> > >         * gcc.dg/Warray-bounds-51.c: Ditto.
> > >         * gcc.dg/Warray-parameter-3.c: Ditto.
> > >         * gcc.dg/Wstringop-overflow-14.c: Ditto.
> > >         * gcc.dg/Wstringop-overflow-21.c: Ditto.
> > >         * gcc.dg/Wstringop-overflow-68.c: Ditto.
> > >         * gcc.dg/Wstringop-overflow-76.c: Ditto.
> > >         * gcc.dg/Warray-bounds-48.c: Ditto.
> > >         * gcc.dg/Wzero-length-array-bounds-2.c: Ditto.
> > >
> >
> > Some of these adjustments cause regressions on arm / aarch64, the exact
> > list depends on the target/flags.
> > See
> > https://people.linaro.org/~christophe.lyon/cross-validation/gcc/trunk/r12-4525-gf36240f8c835d792f788b6724e272fc0a4a4f26f/report-build-info.html
> > for more on details on several combinations.
> >
> > Can you have a look?
> Yes.
Testcase in target-support doesn't match real testcase, .i.e. for v4qi
vectorization, it's
char a[4];
void foo ()
{
  a[0] = 0;
  a[1] = 1;
  a[2] = 2;
  a[3] = 3;
}

vs

typedef struct AC2 { char a[2]; } AC2;
typedef struct AC4 { char a[4]; } AC4;
#define Ac4 (AC4){ 0, 1, 2, 3 }
extern char a2[2];
extern char a4[4];
void
foo ()
{
  *(AC4*)a2 = Ac4;
}

The former can be vectorized by aarch64-linux-gcc, but the latter
can't be which cause ned FAIL, similar for other XPASS cases.

Guess we need exact match for testcase in target-supports.exp.
> >
> > Christophe
> >
> >         * lib/target-supports.exp (check_vect_slp_aligned_store_usage):
> > >         New function.
> > >         (check_effective_target_vect_slp_v2qi_store): Ditto.
> > >         (check_effective_target_vect_slp_v4qi_store): Ditto.
> > >         (check_effective_target_vect_slp_v8qi_store): Ditto.
> > >         (check_effective_target_vect_slp_v16qi_store): Ditto.
> > >         (check_effective_target_vect_slp_v2hi_store): Ditto.
> > >         (check_effective_target_vect_slp_v4hi_store): Ditto.
> > >         (check_effective_target_vect_slp_v2si_store): Ditto.
> > >         (check_effective_target_vect_slp_v4si_store): Ditto.
> > >         * c-c++-common/Wstringop-overflow-2-novec.c: New test.
> > >         * gcc.dg/Warray-bounds-51-novec.c: New test.
> > >         * gcc.dg/Warray-bounds-48-novec.c: New test.
> > >         * gcc.dg/Warray-parameter-3-novec.c: New test.
> > >         * gcc.dg/Wstringop-overflow-14-novec.c: New test.
> > >         * gcc.dg/Wstringop-overflow-21-novec.c: New test.
> > >         * gcc.dg/Wstringop-overflow-76-novec.c: New test.
> > >         * gcc.dg/Wzero-length-array-bounds-2-novec.c: New test.
> > > ---
> > >  gcc/doc/sourcebuild.texi                      |  32 ++
> > >  .../c-c++-common/Wstringop-overflow-2-novec.c | 126 ++++++
> > >  .../c-c++-common/Wstringop-overflow-2.c       |  20 +-
> > >  gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c | 364 ++++++++++++++++++
> > >  gcc/testsuite/gcc.dg/Warray-bounds-48.c       |   4 +-
> > >  gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c |  21 +
> > >  gcc/testsuite/gcc.dg/Warray-bounds-51.c       |   2 +-
> > >  .../gcc.dg/Warray-parameter-3-novec.c         |  16 +
> > >  gcc/testsuite/gcc.dg/Warray-parameter-3.c     |   2 +-
> > >  .../gcc.dg/Wstringop-overflow-14-novec.c      |  16 +
> > >  gcc/testsuite/gcc.dg/Wstringop-overflow-14.c  |   4 +-
> > >  .../gcc.dg/Wstringop-overflow-21-novec.c      |  34 ++
> > >  gcc/testsuite/gcc.dg/Wstringop-overflow-21.c  |   8 +-
> > >  gcc/testsuite/gcc.dg/Wstringop-overflow-68.c  |  17 +-
> > >  .../gcc.dg/Wstringop-overflow-76-novec.c      |  88 +++++
> > >  gcc/testsuite/gcc.dg/Wstringop-overflow-76.c  |  18 +-
> > >  .../Wzero-length-array-bounds-2-novec.c       |  45 +++
> > >  .../gcc.dg/Wzero-length-array-bounds-2.c      |   2 +-
> > >  gcc/testsuite/lib/target-supports.exp         | 182 +++++++++
> > >  19 files changed, 967 insertions(+), 34 deletions(-)
> > >  create mode 100644 gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> > >  create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> > >  create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> > >  create mode 100644 gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> > >  create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> > >  create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> > >  create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> > >  create mode 100644
> > > gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
> > >
> > > diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
> > > index b1fffd5e90f..6a165767630 100644
> > > --- a/gcc/doc/sourcebuild.texi
> > > +++ b/gcc/doc/sourcebuild.texi
> > > @@ -1845,6 +1845,38 @@ Target supports loop vectorization with partial
> > > vectors and
> > >  @item vect_partial_vectors
> > >  Target supports loop vectorization with partial vectors and
> > >  @code{vect-partial-vector-usage} is nonzero.
> > > +
> > > +@item vect_slp_v2qi_store
> > > +Target supports vectorization of 2-byte char stores with 2-byte aligned
> > > +address at plain @option{-O2}.
> > > +
> > > +@item vect_slp_v4qi_store
> > > +Target supports vectorization of 4-byte char stores with 4-byte aligned
> > > +address at plain @option{-O2}.
> > > +
> > > +@item vect_slp_v8qi_store
> > > +Target supports vectorization of 8-byte char stores with 8-byte aligned
> > > +address at plain @option{-O2}.
> > > +
> > > +@item vect_slp_v16qi_store
> > > +Target supports vectorization of 16-byte char stores with 16-byte aligned
> > > +address at plain @option{-O2}.
> > > +
> > > +@item vect_slp_v2hi_store
> > > +Target supports vectorization of 4-byte short stores with 4-byte aligned
> > > +address at plain @option{-O2}.
> > > +
> > > +@item vect_slp_v4hi_store
> > > +Target supports vectorization of 8-byte short stores with 8-byte aligned
> > > +address at plain @option{-O2}.
> > > +
> > > +@item vect_slp_v2si_store
> > > +Target supports vectorization of 8-byte int stores with 8-byte aligned
> > > +address at plain @option{-O2}.
> > > +
> > > +@item vect_slp_v4si_store
> > > +Target supports vectorization of 16-byte int stores with 16-byte aligned
> > > +address at plain @option{-O2}.
> > >  @end table
> > >
> > >  @subsubsection Thread Local Storage attributes
> > > diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> > > b/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> > > new file mode 100644
> > > index 00000000000..3c34ad35a5d
> > > --- /dev/null
> > > +++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> > > @@ -0,0 +1,126 @@
> > > +/* PR middle-end/91458 - inconsistent warning for writing past the end
> > > +   of an array member
> > > +   { dg-do compile }
> > > +   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds
> > > -fno-ipa-icf" } */
> > > +
> > > +void sink (void*);
> > > +
> > > +// Exercise trailing one-element array members.
> > > +
> > > +struct A1
> > > +{
> > > +  char n;
> > > +  char a[1];                    // { dg-message "destination object"
> > > "note" }
> > > +};
> > > +
> > > +// Verify warning for access to a definition with an initializer that
> > > doesn't
> > > +// initialize the one-element array member.
> > > +struct A1 a1__ = { 0 };
> > > +
> > > +void ga1__ (void)
> > > +{
> > > +  a1__.a[0] = 0;
> > > +  a1__.a[1] = 1;                 // { dg-warning
> > > "\\\[-Wstringop-overflow" }
> > > +  a1__.a[2] = 2;                 // { dg-warning
> > > "\\\[-Wstringop-overflow" }
> > > +
> > > +  struct A1 a = { 1 };
> > > +  a.a[0] = 0;
> > > +  a.a[1] = 1;                    // { dg-warning
> > > "\\\[-Wstringop-overflow" }
> > > +  a.a[2] = 2;                    // { dg-warning
> > > "\\\[-Wstringop-overflow" }
> > > +  sink (&a);
> > > +}
> > > +
> > > +// Verify warning for access to a definition with an initializer that
> > > +// initializes the one-element array member to empty.
> > > +struct A1 a1_0 = { 0, { } };
> > > +
> > > +void ga1_0_ (void)
> > > +{
> > > +  a1_0.a[0] = 0;
> > > +  a1_0.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +  a1_0.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +
> > > +  struct A1 a = { 1, { } };
> > > +  a.a[0] = 0;
> > > +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +  sink (&a);
> > > +}
> > > +
> > > +// Verify warning for access to a definition with an initializer that
> > > +// initializes the one-element array member.
> > > +struct A1 a1_1 = { 0, { 1 } };
> > > +
> > > +void ga1_1 (void)
> > > +{
> > > +  a1_1.a[0] = 0;
> > > +  a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +  a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +
> > > +  struct A1 a = { 0, { 1 } };
> > > +  a.a[0] = 0;
> > > +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +  sink (&a);
> > > +}
> > > +
> > > +// Exercise interior one-element array members (verify they're not
> > > +// treated as trailing.
> > > +
> > > +struct A1i
> > > +{
> > > +  char n;
> > > +  char a[1];                    // { dg-message "destination object" }
> > > +  char x;
> > > +};
> > > +
> > > +// Verify warning for access to a definition with an initializer that
> > > doesn't
> > > +// initialize the one-element array member.
> > > +struct A1i a1i__ = { 0 };
> > > +
> > > +void ga1i__ (void)
> > > +{
> > > +  a1i__.a[0] = 0;
> > > +  a1i__.a[1] = 1;                // { dg-warning
> > > "\\\[-Wstringop-overflow" }
> > > +  a1i__.a[2] = 2;                // { dg-warning
> > > "\\\[-Wstringop-overflow" }
> > > +
> > > +  struct A1i a = { 0 };
> > > +  a.a[0] = 0;
> > > +  a.a[1] = 1;                    // { dg-warning
> > > "\\\[-Wstringop-overflow" }
> > > +  a.a[2] = 2;                    // { dg-warning
> > > "\\\[-Wstringop-overflow" }
> > > +  sink (&a);
> > > +}
> > > +
> > > +// Verify warning for access to a definition with an initializer that
> > > +// initializes the one-element array member to empty.
> > > +struct A1 a1i_0 = { 0, { } };
> > > +
> > > +void ga1i_0_ (void)
> > > +{
> > > +  a1i_0.a[0] = 0;
> > > +  a1i_0.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +  a1i_0.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +
> > > +  struct A1 a = { 0, { } };
> > > +  a.a[0] = 0;
> > > +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +  sink (&a);
> > > +}
> > > +
> > > +// Verify warning for access to a definition with an initializer that
> > > +// initializes the one-element array member.
> > > +struct A1 a1i_1 = { 0, { 1 } };
> > > +
> > > +void ga1i_1 (void)
> > > +{
> > > +  a1i_1.a[0] = 0;
> > > +  a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +  a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +
> > > +  struct A1 a = { 0, { 1 } };
> > > +  a.a[0] = 1;
> > > +  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > +  sink (&a);
> > > +}
> > > diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> > > b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> > > index 7d29b5f48c7..ca38bda73f5 100644
> > > --- a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> > > +++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> > > @@ -190,7 +190,7 @@ void ga1__ (void)
> > >    struct A1 a = { 1 };
> > >    a.a[0] = 0;
> > >    a.a[1] = 1;                    // { dg-warning
> > > "\\\[-Wstringop-overflow" }
> > > -  a.a[2] = 2;                    // { dg-warning
> > > "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > +  a.a[2] = 2;                    // { dg-warning
> > > "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store } } }
> > >    sink (&a);
> > >  }
> > >
> > > @@ -207,7 +207,7 @@ void ga1_0_ (void)
> > >    struct A1 a = { 1, { } };
> > >    a.a[0] = 0;
> > >    a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > -  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > "" { xfail { i?86-*-* x86_64-*-* } } }
> > > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > "pr102462" { xfail { vect_slp_v2qi_store } } }
> > >    sink (&a);
> > >  }
> > >
> > > @@ -221,10 +221,10 @@ void ga1_1 (void)
> > >    a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > >    a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > >
> > > -  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> > > "" { target { i?86-*-* x86_64-*-* } } }
> > > +  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> > > "pr102706" { target { vect_slp_v4qi_store } } }
> > >    a.a[0] = 0;
> > > -  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > "" { xfail { i?86-*-* x86_64-*-* } } }
> > > -  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > "" { xfail { i?86-*-* x86_64-*-* } } }
> > > +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > "" { xfail { vect_slp_v4qi_store } } }
> > > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > "" { xfail { vect_slp_v4qi_store } } }
> > >    sink (&a);
> > >  }
> > >
> > > @@ -289,7 +289,7 @@ void ga1i__ (void)
> > >    struct A1i a = { 0 };
> > >    a.a[0] = 0;
> > >    a.a[1] = 1;                    // { dg-warning
> > > "\\\[-Wstringop-overflow" }
> > > -  a.a[2] = 2;                    // { dg-warning
> > > "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > +  a.a[2] = 2;                    // { dg-warning
> > > "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store } } }
> > >    sink (&a);
> > >  }
> > >
> > > @@ -306,7 +306,7 @@ void ga1i_0_ (void)
> > >    struct A1 a = { 0, { } };
> > >    a.a[0] = 0;
> > >    a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > > -  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > "" { xfail { i?86-*-* x86_64-*-* } } }
> > > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > "pr102462" { xfail { vect_slp_v2qi_store } } }
> > >    sink (&a);
> > >  }
> > >
> > > @@ -320,10 +320,10 @@ void ga1i_1 (void)
> > >    a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > >    a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow"
> > > }
> > >
> > > -  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> > > "" { target { i?86-*-* x86_64-*-* } } }
> > > +  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> > > "pr102462" { target { vect_slp_v4qi_store } } }
> > >    a.a[0] = 1;
> > > -  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > "" { xfail { i?86-*-* x86_64-*-* } } }
> > > -  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > "" { xfail { i?86-*-* x86_64-*-* } } }
> > > +  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > "pr102462" { xfail { vect_slp_v4qi_store } } }
> > > +  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > "pr102462" { xfail { vect_slp_v4qi_store } } }
> > >    sink (&a);
> > >  }
> > >
> > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> > > b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> > > new file mode 100644
> > > index 00000000000..da179a2c0f5
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> > > @@ -0,0 +1,364 @@
> > > +/* PR middle-end/91647 - missing -Warray-bounds accessing a zero-length
> > > array
> > > +   of a declared object
> > > +   { dg-do "compile" }
> > > +   { dg-options "-O2 -Wall -fno-tree-vectorize" }
> > > +   { dg-require-effective-target alloca } */
> > > +
> > > +typedef __INT16_TYPE__ int16_t;
> > > +typedef __INT32_TYPE__ int32_t;
> > > +
> > > +void sink (void*);
> > > +
> > > +/* Exercise a true flexible member.  */
> > > +
> > > +struct AX
> > > +{
> > > +  int32_t n;
> > > +  int16_t ax[];     // { dg-message "while referencing 'ax'" "member" }
> > > +};
> > > +
> > > +static void warn_ax_local (struct AX *p)
> > > +{
> > > +  p->ax[0] = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->ax[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > +
> > > +static void nowarn_ax_extern (struct AX *p)
> > > +{
> > > +  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
> > > +}
> > > +
> > > +static void warn_ax_local_buf (struct AX *p)
> > > +{
> > > +  p->ax[0] = 4; p->ax[1] = 5;
> > > +
> > > +  p->ax[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->ax[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->ax[4] = 8;     // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > +
> > > +static void warn_ax_extern_buf (struct AX *p)
> > > +{
> > > +  p->ax[0] = 9; p->ax[1] = 10; p->ax[2] = 11;
> > > +
> > > +  p->ax[3] = 12;    // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->ax[4] = 13;    // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->ax[5] = 14;    // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > +
> > > +static void nowarn_ax_extern_bufx (struct AX *p)
> > > +{
> > > +  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
> > > +}
> > > +
> > > +static void nowarn_ax_ref (struct AX *p)
> > > +{
> > > +  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
> > > +}
> > > +
> > > +void test_ax (struct AX *p, unsigned n)
> > > +{
> > > +  {
> > > +    struct AX sax;  // { dg-message "defined here" "struct definition" }
> > > +    warn_ax_local (&sax);
> > > +    sink (&sax);
> > > +  }
> > > +
> > > +  {
> > > +    extern
> > > +      struct AX xsax;
> > > +    nowarn_ax_extern (&xsax);
> > > +    sink (&xsax);
> > > +  }
> > > +
> > > +  {
> > > +    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
> > > +    char ax_buf_p2[sizeof (struct AX) + 2 * sizeof (int16_t)];
> > > +    warn_ax_local_buf ((struct AX*) ax_buf_p2);
> > > +    sink (ax_buf_p2);
> > > +  }
> > > +
> > > +  {
> > > +    /* Verify out-of-bounds access to the extern BUF with a known
> > > +       bound is diagnosed.  */
> > > +    extern char ax_buf_p3[sizeof (struct AX) + 3 * sizeof (int16_t)];
> > > +    warn_ax_extern_buf ((struct AX*) ax_buf_p3);
> > > +    sink (ax_buf_p3);
> > > +  }
> > > +
> > > +  {
> > > +    /* Verify that accesses to BUFX with an unknown bound are not
> > > +       diagnosed.  */
> > > +    extern char bufx[];
> > > +    nowarn_ax_extern_bufx ((struct AX*) bufx);
> > > +    sink (bufx);
> > > +  }
> > > +
> > > +  {
> > > +    /* Verify that accesses to BUFN with a runtime bound are not
> > > +       diagnosed.  */
> > > +    char bufn[n];
> > > +    nowarn_ax_extern_bufx ((struct AX*) bufn);
> > > +    sink (bufn);
> > > +  }
> > > +
> > > +  nowarn_ax_ref (p);
> > > +}
> > > +
> > > +
> > > +/* Exercise a zero-length trailing member array.  It's the same as above
> > > +   except that extern declarations with no definitions are considered to
> > > +   have zero elements (they can't be initialized to have any).  */
> > > +
> > > +struct A0
> > > +{
> > > +  int32_t n;
> > > +  int16_t a0[0];    // { dg-message "while referencing 'a0'" "member" }
> > > +};
> > > +
> > > +static void warn_a0_local (struct A0 *p)
> > > +{
> > > +  p->a0[0] = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->a0[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > +
> > > +static void warn_a0_extern (struct A0 *p)
> > > +{
> > > +  p->a0[0] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->a0[1] = 3;     // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > +
> > > +static void warn_a0_local_buf (struct A0 *p)
> > > +{
> > > +  p->a0[0] = 4; p->a0[1] = 5;
> > > +
> > > +  p->a0[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->a0[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->a0[4] = 8;     // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > +
> > > +static void warn_a0_extern_buf (struct A0 *p)
> > > +{
> > > +  p->a0[0] = 9; p->a0[1] = 10; p->a0[2] = 11;
> > > +
> > > +  p->a0[3] = 12;    // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->a0[4] = 13;    // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->a0[5] = 14;    // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > +
> > > +static void nowarn_a0_extern_bufx (struct A0 *p)
> > > +{
> > > +  p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
> > > +}
> > > +
> > > +static void nowarn_a0_ref (struct A0 *p)
> > > +{
> > > +  p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
> > > +}
> > > +
> > > +void test_a0 (struct A0 *p, unsigned n)
> > > +{
> > > +  {
> > > +    struct A0 sa0;  // { dg-message "defined here" "struct definition" }
> > > +    warn_a0_local (&sa0);
> > > +    sink (&sa0);
> > > +  }
> > > +
> > > +  {
> > > +    extern
> > > +      struct A0 xsa0;  // { dg-message "defined here" "struct definition"
> > > }
> > > +    warn_a0_extern (&xsa0);
> > > +    sink (&xsa0);
> > > +  }
> > > +
> > > +  {
> > > +    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
> > > +    char a0_buf_p2[sizeof (struct A0) + 2 * sizeof (int16_t)];
> > > +    warn_a0_local_buf ((struct A0*) a0_buf_p2);
> > > +    sink (a0_buf_p2);
> > > +  }
> > > +
> > > +  {
> > > +    /* Verify out-of-bounds access to the extern BUF with a known
> > > +       bound is diagnosed.  */
> > > +    extern char a0_buf_p3[sizeof (struct A0) + 3 * sizeof (int16_t)];
> > > +    warn_a0_extern_buf ((struct A0*) a0_buf_p3);
> > > +    sink (a0_buf_p3);
> > > +  }
> > > +
> > > +  {
> > > +    /* Verify that accesses to BUFX with an unknown bound are not
> > > +       diagnosed.  */
> > > +    extern char bufx[];
> > > +    nowarn_a0_extern_bufx ((struct A0*) bufx);
> > > +    sink (bufx);
> > > +  }
> > > +
> > > +  {
> > > +    /* Verify that accesses to BUFN with a runtime bound are not
> > > +       diagnosed.  */
> > > +    char bufn[n];
> > > +    nowarn_a0_extern_bufx ((struct A0*) bufn);
> > > +    sink (bufn);
> > > +  }
> > > +
> > > +  nowarn_a0_ref (p);
> > > +}
> > > +
> > > +
> > > +/* Exercise a one-element trailing member array.  It's the same as above
> > > +   except that it has exactly one element.  */
> > > +
> > > +struct A1
> > > +{
> > > +  int32_t n;
> > > +  int16_t a1[1];    // { dg-message "while referencing 'a1'" }
> > > +};
> > > +
> > > +static void warn_a1_local_noinit (struct A1 *p)
> > > +{
> > > +  p->a1[0] = 0;
> > > +  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > +
> > > +static void warn_a1_extern (struct A1 *p)
> > > +{
> > > +  p->a1[0] = 0;
> > > +  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > +
> > > +static void warn_a1_init (struct A1 *p)
> > > +{
> > > +  p->a1[0] = 0;
> > > +  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > +
> > > +static void warn_a1_local_buf (struct A1 *p)
> > > +{
> > > +  p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3;
> > > +
> > > +  p->a1[4] = 4;     // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > +
> > > +static void warn_a1_extern_buf (struct A1 *p)
> > > +{
> > > +  p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3; p->a1[4] = 4;
> > > +
> > > +  p->a1[5] = 5;     // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > +
> > > +static void nowarn_a1_extern_bufx (struct A1 *p)
> > > +{
> > > +  p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
> > > +}
> > > +
> > > +static void nowarn_a1_ref (struct A1 *p)
> > > +{
> > > +  p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
> > > +}
> > > +
> > > +void test_a1 (struct A1 *p, unsigned n)
> > > +{
> > > +  {
> > > +    struct A1 a1;
> > > +    warn_a1_local_noinit (&a1);
> > > +    sink (&a1);
> > > +  }
> > > +
> > > +  {
> > > +    extern struct A1 a1x;
> > > +    warn_a1_extern (&a1x);
> > > +    sink (&a1x);
> > > +}
> > > +  {
> > > +    struct A1 a1 = { 0, { 1 } };
> > > +    warn_a1_init (&a1);
> > > +    sink (&a1);
> > > +  }
> > > +
> > > +  {
> > > +    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
> > > +    char buf_p2[sizeof (struct A1) + 2 * sizeof (int16_t)];
> > > +    warn_a1_local_buf ((struct A1*) buf_p2);
> > > +    sink (buf_p2);
> > > +  }
> > > +
> > > +  {
> > > +    /* Verify out-of-bounds access to the extern BUF with a known
> > > +       bound is diagnosed.  */
> > > +    extern char a1_buf_p3[sizeof (struct A1) + 3 * sizeof (int16_t)];
> > > +    warn_a1_extern_buf ((struct A1*) a1_buf_p3);
> > > +    sink (a1_buf_p3);
> > > +  }
> > > +
> > > +  {
> > > +    /* Verify that accesses to BUFX with an unknown bound are not
> > > +       diagnosed.  */
> > > +    extern char bufx[];
> > > +    nowarn_a1_extern_bufx ((struct A1*) bufx);
> > > +    sink (bufx);
> > > +  }
> > > +
> > > +  {
> > > +    /* Verify that accesses to BUFN with a runtime bound are not
> > > +       diagnosed.  */
> > > +    char bufn[n];
> > > +    nowarn_a1_extern_bufx ((struct A1*) bufn);
> > > +    sink (bufn);
> > > +  }
> > > +
> > > +  nowarn_a1_ref (p);
> > > +}
> > > +
> > > +
> > > +/* Exercise a two-element trailing member array.  It's treated
> > > +   the same as an interior array member.  */
> > > +
> > > +struct A2
> > > +{
> > > +  int32_t n;
> > > +  int16_t a2[2];    // { dg-message "while referencing 'a2'" }
> > > +};
> > > +
> > > +static void warn_a2_noinit (struct A2 *p)
> > > +{
> > > +  p->a2[0] = 0; p->a2[1] = 1;
> > > +
> > > +  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > +
> > > +static void warn_a2_init (struct A2 *p)
> > > +{
> > > +  p->a2[0] = 0; p->a2[1] = 1;
> > > +
> > > +  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->a2[9] = 9;     // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > +
> > > +static void warn_a2_ref (struct A2 *p)
> > > +{
> > > +  p->a2[0] = 0; p->a2[1] = 1;
> > > +
> > > +  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->a2[9] = 9;     // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > +
> > > +void test_a2 (struct A2 *p)
> > > +{
> > > +  {
> > > +    struct A2 a2;
> > > +    warn_a2_noinit (&a2);
> > > +    sink (&a2);
> > > +  }
> > > +
> > > +  {
> > > +    struct A2 a2 = { 0, { 1, 2 } };
> > > +    warn_a2_init (&a2);
> > > +    sink (&a2);
> > > +  }
> > > +
> > > +  warn_a2_ref (p);
> > > +}
> > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> > > b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> > > index 13373d1e99e..19b7634c063 100644
> > > --- a/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> > > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> > > @@ -30,7 +30,7 @@ static void nowarn_ax_extern (struct AX *p)
> > >
> > >  static void warn_ax_local_buf (struct AX *p)
> > >  {
> > > -  p->ax[0] = 4; p->ax[1] = 5;
> > > +  p->ax[0] = 4; p->ax[1] = 5;  // { dg-warning "\\\[-Wstringop-overflow"
> > > "pr102706" { target { vect_slp_v2hi_store &&  { ! vect_slp_v4hi_store } } }
> > > }
> > >
> > >    p->ax[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> > >    p->ax[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> > > @@ -130,7 +130,7 @@ static void warn_a0_extern (struct A0 *p)
> > >
> > >  static void warn_a0_local_buf (struct A0 *p)
> > >  {
> > > -  p->a0[0] = 4; p->a0[1] = 5;
> > > +  p->a0[0] = 4; p->a0[1] = 5;  // { dg-warning "\\\[-Wstringop-overflow"
> > > "pr102706" { target { vect_slp_v2hi_store && { ! vect_slp_v4hi_store } } } }
> > >
> > >    p->a0[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> > >    p->a0[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> > > b/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> > > new file mode 100644
> > > index 00000000000..ef8056d9b7f
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> > > @@ -0,0 +1,21 @@
> > > +/* PR middle-end/92333 - missing variable name referencing VLA in warnings
> > > +   PR middle-end/82608 - missing -Warray-bounds on an out-of-bounds VLA
> > > index
> > > +   { dg-do compile }
> > > +   { dg-options "-O2 -Wall -fno-tree-vectorize" }  */
> > > +
> > > +void sink (void*);
> > > +
> > > +void test_struct_char_vla_location (void)
> > > +{
> > > +  unsigned nelts = 7;
> > > +
> > > +  struct {
> > > +    char cvla[nelts]; // { dg-message "declared here|while referencing" }
> > > +  } s;
> > > +
> > > +  s.cvla[0] = __LINE__;
> > > +  s.cvla[nelts - 1] = 0;
> > > +  s.cvla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
> > > +
> > > +  sink (&s);
> > > +}
> > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> > > b/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> > > index de60d87ab95..8b589f38191 100644
> > > --- a/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> > > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> > > @@ -39,7 +39,7 @@ void test_struct_char_vla_location (void)
> > >    } s;
> > >
> > >    s.cvla[0] = __LINE__;
> > > -  s.cvla[nelts - 1] = 0; // { dg-warning "\\\[-Wstringop-overflow" "" {
> > > target { i?86-*-* x86_64-*-* } } }
> > > +  s.cvla[nelts - 1] = 0; // { dg-warning "\\\[-Wstringop-overflow"
> > > "pr102706" { target { vect_slp_v2qi_store } } }
> > >    s.cvla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
> > >
> > >    sink (&s);
> > > diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> > > b/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> > > new file mode 100644
> > > index 00000000000..5089d555392
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> > > @@ -0,0 +1,16 @@
> > > +/* PR c/50584 - No warning for passing small array to C99 static array
> > > +   declarator
> > > +   { dg-do compile }
> > > +   { dg-options "-Wall -Warray-parameter=1" } */
> > > +
> > > +/* Also verify that -Warray-bounds doesn't trigger for ordinary array
> > > +   parameters...  */
> > > +#pragma GCC optimize ("2,no-tree-vectorize")
> > > +
> > > +/* ...but does for static arrays.  */
> > > +__attribute__ ((noipa)) void
> > > +gcas3 (char a[static 3])
> > > +{
> > > +  a[0] = 0; a[1] = 1; a[2] = 2;
> > > +  a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
> > > +}
> > > diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> > > b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> > > index e8a269c85c6..b6ed8daf51c 100644
> > > --- a/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> > > +++ b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> > > @@ -77,7 +77,7 @@ gia3 (int a[3])
> > >  __attribute__ ((noipa)) void
> > >  gcas3 (char a[static 3])
> > >  {
> > > -  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow"
> > > "" { target { i?86-*-* x86_64-*-* } } }
> > > +  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow"
> > > "pr102706" { target { vect_slp_v4qi_store } } }
> > >    a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
> > >  }
> > >
> > > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> > > b/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> > > new file mode 100644
> > > index 00000000000..de39eaaeb95
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> > > @@ -0,0 +1,16 @@
> > > +/* Test to verify that past-the-end multibyte writes via lvalues of wider
> > > +   types than char are diagnosed.
> > > +   { dg-do compile }
> > > +   { dg-require-effective-target int32plus }
> > > +   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds" }  */
> > > +
> > > +typedef __INT16_TYPE__  int16_t;
> > > +
> > > +char a4[4], a8[8], a16[16];
> > > +
> > > +void test_int16 (void)
> > > +{
> > > +  char *p = a4 + 1;
> > > +  *(int16_t*)p = 0;
> > > +  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a
> > > region of size 1" }
> > > +}
> > > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> > > b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> > > index 7683084e46e..c4a3f05d883 100644
> > > --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> > > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> > > @@ -36,8 +36,8 @@ void test_memcpy_cond (int i)
> > >  void test_int16 (void)
> > >  {
> > >    char *p = a4 + 1;
> > > -  *(int16_t*)p = 0;    // { dg-warning "writing 4 bytes into a region of
> > > size 3" "" { target { i?86-*-* x86_64-*-* } } }
> > > -  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a
> > > region of size 1" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > +  *(int16_t*)p = 0;    // { dg-warning "writing 4 bytes into a region of
> > > size 3" "pr102706" { target { vect_slp_v2hi_store } } }
> > > +  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a
> > > region of size 1" "pr102706" { xfail { vect_slp_v2hi_store } } }
> > >  }
> > >
> > >
> > > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> > > b/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> > > new file mode 100644
> > > index 00000000000..6f83548e902
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> > > @@ -0,0 +1,34 @@
> > > +/* PR middle-end/92312 - bogus -Wstringop-overflow storing into a trailing
> > > +   array backed by larger buffer
> > > +   { dg-do compile }
> > > +   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds" } */
> > > +
> > > +struct S0 { char a, b[0]; };
> > > +
> > > +void sink (void*);
> > > +
> > > +void test_store_zero_length (int i)
> > > +{
> > > +  char a[3];
> > > +  struct S0 *p = (struct S0*)a;
> > > +  p->a = 0;
> > > +  p->b[0] = 0;
> > > +  p->b[1] = 1;                      // { dg-bogus
> > > "\\\[-Wstringop-overflow" }
> > > +  p->b[2] = 2;                      // { dg-warning
> > > "\\\[-Wstringop-overflow" }
> > > +  p->b[i] = 2;
> > > +  sink (p);
> > > +}
> > > +
> > > +struct Sx { char a, b[]; };
> > > +
> > > +void test_store_flexarray (int i)
> > > +{
> > > +  char a[3];
> > > +  struct Sx *p = (struct Sx*)a;
> > > +  p->a = 0;
> > > +  p->b[0] = 0;
> > > +  p->b[1] = 1;                      // { dg-bogus
> > > "\\\[-Wstringop-overflow" }
> > > +  p->b[2] = 1;                      // { dg-warning
> > > "\\\[-Wstringop-overflow" }
> > > +  p->b[i] = 2;
> > > +  sink (p);
> > > +}
> > > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> > > b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> > > index d88bde9c740..3fccfc9a798 100644
> > > --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> > > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> > > @@ -23,10 +23,10 @@ void test_store_zero_length (int i)
> > >  {
> > >    char a[3];
> > >    struct S0 *p = (struct S0*)a;
> > > -  p->a = 0;                         // { dg-warning
> > > "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> > > +  p->a = 0;                         // { dg-warning
> > > "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v4qi_store } } }
> > >    p->b[0] = 0;
> > >    p->b[1] = 1;                      // { dg-bogus
> > > "\\\[-Wstringop-overflow" }
> > > -  p->b[2] = 2;                      // { dg-warning
> > > "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > +  p->b[2] = 2;                      // { dg-warning
> > > "\\\[-Wstringop-overflow" "pr102706" { xfail { vect_slp_v4qi_store } } }
> > >    p->b[i] = 2;
> > >    sink (p);
> > >  }
> > > @@ -50,10 +50,10 @@ void test_store_flexarray (int i)
> > >  {
> > >    char a[3];
> > >    struct Sx *p = (struct Sx*)a;
> > > -  p->a = 0;                         // { dg-warning
> > > "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> > > +  p->a = 0;                         // { dg-warning
> > > "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v4qi_store } } }
> > >    p->b[0] = 0;
> > >    p->b[1] = 1;                      // { dg-bogus
> > > "\\\[-Wstringop-overflow" }
> > > -  p->b[2] = 1;                      // { dg-warning
> > > "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > +  p->b[2] = 1;                      // { dg-warning
> > > "\\\[-Wstringop-overflow" "pr102706" { xfail { vect_slp_v4qi_store } } }
> > >    p->b[i] = 2;
> > >    sink (p);
> > >  }
> > > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> > > b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> > > index 09df0004991..04e91afb8bc 100644
> > > --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> > > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> > > @@ -58,11 +58,18 @@ void warn_comp_lit_zero (void)
> > >  void warn_comp_lit (void)
> > >  {
> > >    *(AC2*)a1 = Ac2;      // { dg-warning "writing 2 bytes into a region of
> > > size 1" "pr101475" { xfail *-*-* } }
> > > -  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> > > size 2" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> > > -  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> > > size 3" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> > > -  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> > > size 4" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> > > -  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> > > size 7" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> > > -  *(AC16*)a15 = Ac16;   // { dg-warning "writing 16 bytes into a region
> > > of size 15" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> > > +  // After vectorization, below codes are optimized to
> > > +  // MEM <vector(4) char> [(char *)&a2] = { 0, 1, 2, 3 };
> > > +  // MEM <vector(4) char> [(char *)&a3] = { 0, 1, 2, 3 };
> > > +  // MEM <vector(8) char> [(char *)&a4] = { 0, 1, 2, 3, 4, 5, 6, 7 };
> > > +  // MEM <vector(8) char> [(char *)&a7] = { 0, 1, 2, 3, 4, 5, 6, 7 };
> > > +  // MEM <vector(16) char> [(char *)&a15] = { 0, 1, 2, 3, 4, 5, 6, 7, 8,
> > > 9, 10, 11, 12, 13, 14, 15 };
> > > +  // and warning should be expected, refer to PR102722.
> > > +  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> > > size 2" "pr101475" { xfail { ! { vect_slp_v4qi_store } } } }
> > > +  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> > > size 3" "pr101475" { xfail { ! { vect_slp_v4qi_store } } } }
> > > +  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> > > size 4" "pr101475" { xfail { ! { vect_slp_v8qi_store } } } }
> > > +  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> > > size 7" "pr101475" { xfail { ! { vect_slp_v8qi_store } } } }
> > > +  *(AC16*)a15 = Ac16;   // { dg-warning "writing 16 bytes into a region
> > > of size 15" "pr101475" { xfail { ! { vect_slp_v16qi_store } } } }
> > >  }
> > >
> > >  void warn_aggr_decl (void)
> > > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> > > b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> > > new file mode 100644
> > > index 00000000000..71c643b62fb
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> > > @@ -0,0 +1,88 @@
> > > +/* Verify warnings and notes for MAX_EXPRs involving either pointers
> > > +   to distinct objects or one to a known object and the other to
> > > +   an unknown one.  Unlike for the same object, for unrelated objects
> > > +   the expected warnings and notes are the same as for MIN_EXPR: when
> > > +   the order of the objects in the address space cannot be determined
> > > +   the larger of them is assumed to be used.  (This is different for
> > > +   distinct struct members where the order is given.)
> > > +   The relational expressions are strictly invalid but that should be
> > > +   diagnosed by a separate warning.
> > > +   { dg-do compile }
> > > +   { dg-options "-O2 -Wno-array-bounds -fno-tree-vectorize" } */
> > > +
> > > +#define MAX(p, q) ((p) > (q) ? (p) : (q))
> > > +
> > > +/* Verify that even for MAX_EXPR and like for MIN_EXPR, the note points
> > > +   to the larger of the two objects and mentions the offset into it
> > > +   (although the offset might be better included in the warning).  */
> > > +extern char a3[3];
> > > +extern char a5[5];  // { dg-message "at offset 5 into destination object
> > > 'a5' of size 5" "note" }
> > > +
> > > +void max_a3_a5 (int i)
> > > +{
> > > +  char *p = a3 + i;
> > > +  char *q = a5 + i;
> > > +
> > > +  /* The relational expression below is invalid and should be diagnosed
> > > +     by its own warning independently of -Wstringop-overflow.  */
> > > +  char *d = MAX (p, q);
> > > +
> > > +  d[2] = 0;
> > > +  d[3] = 0;
> > > +  d[4] = 0;
> > > +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > 0" }
> > > +}
> > > +
> > > +
> > > +// Same as above but with the larger array as the first MAX_EXPR operand.
> > > +extern char b4[4];
> > > +extern char b6[6];  // { dg-message "at offset 6 into destination object
> > > 'b6' of size 6" "note" }
> > > +
> > > +void max_b6_b4 (int i)
> > > +{
> > > +  char *p = b6 + i;
> > > +  char *q = b4 + i;
> > > +  char *d = MAX (p, q);
> > > +
> > > +  d[3] = 0;
> > > +  d[4] = 0;
> > > +  d[5] = 0;
> > > +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > 0" }
> > > +}
> > > +
> > > +struct A3_5
> > > +{
> > > +  char a3[3];  // { dg-message "at offset 3 into destination object 'a3'
> > > of size 3" "pr??????" { xfail *-*-* } }
> > > +  char a5[5];  // { dg-message "at offset 5 into destination object 'a5'
> > > of size 5" "note" }
> > > +};
> > > +
> > > +void max_A3_A5 (int i, struct A3_5 *pa3_5)
> > > +{
> > > +  char *p = pa3_5->a3 + i;
> > > +  char *q = pa3_5->a5 + i;
> > > +
> > > +  char *d = MAX (p, q);
> > > +  d[2] = 0;
> > > +  d[3] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > 0" "pr??????" { xfail *-*-* } }
> > > +  d[4] = 0;
> > > +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > 0" }
> > > +}
> > > +
> > > +
> > > +struct B4_B6
> > > +{
> > > +  char b4[4];
> > > +  char b6[6];       // { dg-message "at offset 6 into destination object
> > > 'b6' of size 6" "note" }
> > > +};
> > > +
> > > +void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
> > > +{
> > > +  char *p = pb4_b6->b6 + i;
> > > +  char *q = pb4_b6->b4 + i;
> > > +  char *d = MAX (p, q);
> > > +
> > > +  d[3] = 0;
> > > +  d[4] = 0;
> > > +  d[5] = 0;
> > > +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > 0" }
> > > +}
> > > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> > > b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> > > index 0c7b53ccc0b..52467267a04 100644
> > > --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> > > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> > > @@ -27,10 +27,10 @@ void max_a3_a5 (int i)
> > >       by its own warning independently of -Wstringop-overflow.  */
> > >    char *d = MAX (p, q);
> > >
> > > -  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of
> > > size 3" "" { target { i?86-*-* x86_64-*-* } } }
> > > +  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of
> > > size 3" "pr102706" { target { vect_slp_v4qi_store } } }
> > >    d[3] = 0;
> > >    d[4] = 0;
> > > -  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > 0" "pr102706" { xfail { vect_slp_v4qi_store } } }
> > >  }
> > >
> > >
> > > @@ -44,10 +44,10 @@ void max_b6_b4 (int i)
> > >    char *q = b4 + i;
> > >    char *d = MAX (p, q);
> > >
> > > -  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of
> > > size 3" "" { target { i?86-*-* x86_64-*-* } } }
> > > +  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of
> > > size 3" "pr102706" { target { vect_slp_v4qi_store } } }
> > >    d[4] = 0;
> > >    d[5] = 0;
> > > -  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > 0" "pr102706" { xfail { vect_slp_v4qi_store } } }
> > >  }
> > >
> > >
> > > @@ -82,7 +82,8 @@ void max_d8_p (char *q, int i)
> > >  struct A3_5
> > >  {
> > >    char a3[3];  // { dg-message "at offset 3 into destination object 'a3'
> > > of size 3" "pr??????" { xfail *-*-* } }
> > > -  char a5[5];  // { dg-message "at offset 5 into destination object 'a5'
> > > of size 5" "note" { xfail { i?86-*-* x86_64-*-* } } }
> > > +  // refer to pr102697 for xfail
> > > +  char a5[5];  // { dg-message "at offset 5 into destination object 'a5'
> > > of size 5" "note" { xfail { vect_slp_v4qi_store } } }
> > >  };
> > >
> > >  void max_A3_A5 (int i, struct A3_5 *pa3_5)
> > > @@ -95,14 +96,15 @@ void max_A3_A5 (int i, struct A3_5 *pa3_5)
> > >    d[2] = 0;
> > >    d[3] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > 0" "pr??????" { xfail *-*-* } }
> > >    d[4] = 0;
> > > -  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > 0" "pr102697" { xfail { vect_slp_v4qi_store } } }
> > >  }
> > >
> > >
> > >  struct B4_B6
> > >  {
> > >    char b4[4];
> > > -  char b6[6];       // { dg-message "at offset
> > > \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6"
> > > "note" { xfail { i?86-*-* x86_64-*-* } } }
> > > +  // refer to pr102697 for xfail
> > > +  char b6[6];       // { dg-message "at offset
> > > \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6"
> > > "note" { xfail { vect_slp_v4qi_store } } }
> > >  };
> > >
> > >  void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
> > > @@ -114,7 +116,7 @@ void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
> > >    d[3] = 0;
> > >    d[4] = 0;
> > >    d[5] = 0;
> > > -  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > 0" "pr102697" { xfail { vect_slp_v4qi_store } } }
> > >  }
> > >
> > >
> > > diff --git a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
> > > b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
> > > new file mode 100644
> > > index 00000000000..8e023b7cfa7
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
> > > @@ -0,0 +1,45 @@
> > > +/* Test to verify that -Wzero-length-bounds and not -Warray-bounds is
> > > +   issued for accesses to interior zero-length array members that are
> > > +   within the bounds of the enclosing struct.
> > > +   { dg-do compile }
> > > +   { dg-options "-O2 -Wall -fno-tree-vectorize" } */
> > > +
> > > +void sink (void*);
> > > +
> > > +struct A { int i; };
> > > +struct B { int j; struct A a[0]; };
> > > +
> > > +struct C
> > > +{
> > > +  struct B b1;
> > > +  struct B b2;
> > > +};
> > > +
> > > +char cbuf1[1 * sizeof (struct C)];
> > > +char cbuf2[2 * sizeof (struct C)] = { };
> > > +
> > > +void test_C_global_buf (void)
> > > +{
> > > +  struct C *p = (struct C*)&cbuf1;
> > > +
> > > +  p->b1.a[-1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->b1.a[ 0].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
> > > +  p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  sink (p);
> > > +
> > > +  p->b2.a[ 0].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->b2.a[ 1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  sink (p);
> > > +
> > > +  p = (struct C*)&cbuf2;
> > > +  p->b1.a[-1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->b1.a[ 0].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
> > > +  p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
> > > +  sink (p);
> > > +
> > > +  p->b2.a[ 0].i = 0;
> > > +  p->b2.a[ 1].i = 0;
> > > +  p->b2.a[ 2].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  p->b2.a[ 3].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > +  sink (p);
> > > +}
> > > diff --git a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> > > b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> > > index 841b2bfa122..b2321495afc 100644
> > > --- a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> > > +++ b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> > > @@ -87,7 +87,7 @@ void test_C_global_buf (void)
> > >    p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
> > >    sink (p);
> > >
> > > -  p->b2.a[ 0].i = 0;
> > > +  p->b2.a[ 0].i = 0;    // { dg-warning "\\\[-Wstringop-overflow"
> > > "pr102706" { target { vect_slp_v2si_store &&  { ! vect_slp_v4si_store } } }
> > > }
> > >    p->b2.a[ 1].i = 0;
> > >    p->b2.a[ 2].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > >    p->b2.a[ 3].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > diff --git a/gcc/testsuite/lib/target-supports.exp
> > > b/gcc/testsuite/lib/target-supports.exp
> > > index 9ebca7ac007..1c8b1ebb86e 100644
> > > --- a/gcc/testsuite/lib/target-supports.exp
> > > +++ b/gcc/testsuite/lib/target-supports.exp
> > > @@ -7580,6 +7580,188 @@ proc
> > > check_effective_target_vect_element_align_preferred { } {
> > >                    && [check_effective_target_vect_variable_length] }]
> > >  }
> > >
> > > +# Return true if vectorization of v2qi/v4qi/v8qi/v16qi/v2hi store is
> > > enabed.
> > > +# Return zero if the desirable pattern isn't found.
> > > +# It's used by Warray-bounds/Wstringop-overflow testcases which are
> > > +# regressed by O2 vectorization, refer to PR102697/PR102462/PR102706
> > > +proc check_vect_slp_aligned_store_usage { pattern macro } {
> > > +    global tool
> > > +
> > > +    set result [check_compile slp_aligned_store_usage assembly {
> > > +       char a[16] __attribute__ ((aligned (16)));
> > > +       short b[4] __attribute__((aligned(8)));
> > > +       int c[4] __attribute__((aligned(16)));
> > > +       #ifdef TEST_V8QI
> > > +       void
> > > +       foo ()
> > > +       {
> > > +           a[0] = 0;
> > > +           a[1] = 1;
> > > +           a[2] = 2;
> > > +           a[3] = 3;
> > > +           a[4] = 4;
> > > +           a[5] = 5;
> > > +           a[6] = 6;
> > > +           a[7] = 7;
> > > +       }
> > > +       #elif TEST_V16QI
> > > +       void
> > > +       foo1 ()
> > > +       {
> > > +           a[0] = 0;
> > > +           a[1] = 1;
> > > +           a[2] = 2;
> > > +           a[3] = 3;
> > > +           a[4] = 4;
> > > +           a[5] = 5;
> > > +           a[6] = 6;
> > > +           a[7] = 7;
> > > +           a[8] = 8;
> > > +           a[9] = 9;
> > > +           a[10] = 10;
> > > +           a[11] = 11;
> > > +           a[12] = 12;
> > > +           a[13] = 13;
> > > +           a[14] = 14;
> > > +           a[15] = 15;
> > > +       }
> > > +       #elif TEST_V4QI
> > > +       void
> > > +       foo2 ()
> > > +       {
> > > +           a[0] = 0;
> > > +           a[1] = 1;
> > > +           a[2] = 2;
> > > +           a[3] = 3;
> > > +       }
> > > +       #elif TEST_V2QI
> > > +       void
> > > +       foo3 ()
> > > +       {
> > > +           a[0] = 0;
> > > +           a[1] = 1;
> > > +       }
> > > +       #elif TEST_V2HI
> > > +       void
> > > +       foo4 ()
> > > +       {
> > > +           b[0] = 0;
> > > +           b[1] = 1;
> > > +       }
> > > +       #elif TEST_V4HI
> > > +       void
> > > +       foo5 ()
> > > +       {
> > > +           b[0] = 0;
> > > +           b[1] = 1;
> > > +           b[2] = 2;
> > > +           b[3] = 3;
> > > +       }
> > > +       #elif TEST_V2SI
> > > +       void
> > > +       foo6 ()
> > > +       {
> > > +           c[0] = 0;
> > > +           c[1] = 1;
> > > +       }
> > > +       #elif TEST_V4SI
> > > +       void
> > > +       foo7 ()
> > > +       {
> > > +           c[0] = 0;
> > > +           c[1] = 1;
> > > +           c[2] = 2;
> > > +           c[3] = 3;
> > > +       }
> > > +       #endif
> > > +    } "-O2 -fopt-info-all -D$macro" ]
> > > +
> > > +      # Get compiler emitted messages and delete generated file.
> > > +      set lines [lindex $result 0]
> > > +      set output [lindex $result 1]
> > > +      remote_file build delete $output
> > > +
> > > +      # Check pattern exits in lines, set it to zero if not found.
> > > +      if { [regexp $pattern $lines] } then {
> > > +        return 1
> > > +      }
> > > +
> > > +    return 0
> > > +}
> > > +
> > > +# Return the true if target support vectorization of 2-byte char stores
> > > +# with 2-byte aligned address at plain O2.
> > > +proc check_effective_target_vect_slp_v2qi_store { } {
> > > +    set pattern {add new stmt: MEM <vector\(2\) char>}
> > > +    set macro "TEST_V2QI"
> > > +    return [check_cached_effective_target vect_slp_v2qi_store {
> > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro] }]
> > > +
> > > +}
> > > +
> > > +# Return the true if target support vectorization of 4-byte char stores
> > > +# with 4-byte aligned address at plain O2.
> > > +proc check_effective_target_vect_slp_v4qi_store { } {
> > > +    set pattern {add new stmt: MEM <vector\(4\) char>}
> > > +    set macro "TEST_V4QI"
> > > +    return [check_cached_effective_target vect_slp_v4qi_store {
> > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > > +}
> > > +
> > > +# Return the true if target support vectorization of 8-byte char stores
> > > +# with 8-byte aligned address at plain O2.
> > > +proc check_effective_target_vect_slp_v8qi_store { } {
> > > +    set pattern {add new stmt: MEM <vector\(8\) char>}
> > > +    set macro "TEST_V8QI"
> > > +    return [check_cached_effective_target vect_slp_v8qi_store {
> > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > > +}
> > > +
> > > +# Return the true if target support vectorization of 16-byte char stores
> > > +# with 16-byte aligned address at plain O2.
> > > +proc check_effective_target_vect_slp_v16qi_store { } {
> > > +    set pattern {add new stmt: MEM <vector\(16\) char>}
> > > +    set macro "TEST_V16QI"
> > > +    return [check_cached_effective_target vect_slp_v16qi_store {
> > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > > +}
> > > +
> > > +# Return the true if target support vectorization of 4-byte short stores
> > > +# with 4-byte aligned address at plain O2.
> > > +proc check_effective_target_vect_slp_v2hi_store { } {
> > > +    set pattern {add new stmt: MEM <vector\(2\) short int>}
> > > +    set macro "TEST_V2HI"
> > > +    return [check_cached_effective_target vect_slp_v2hi_store {
> > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > > +}
> > > +
> > > +# Return the true if target support vectorization of 8-byte short stores
> > > +# with 8-byte aligned address at plain O2.
> > > +proc check_effective_target_vect_slp_v4hi_store { } {
> > > +    set pattern {add new stmt: MEM <vector\(4\) short int>}
> > > +    set macro "TEST_V4HI"
> > > +    return [check_cached_effective_target vect_slp_v4hi_store {
> > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > > +}
> > > +
> > > +# Return the true if target support vectorization of 8-byte int stores
> > > +# with 8-byte aligned address at plain O2.
> > > +proc check_effective_target_vect_slp_v2si_store { } {
> > > +    set pattern {add new stmt: MEM <vector\(2\) int>}
> > > +    set macro "TEST_V2SI"
> > > +    return [check_cached_effective_target vect_slp_v2si_store {
> > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > > +}
> > > +
> > > +# Return the true if target support vectorization of 16-byte int stores
> > > +# with 16-byte aligned address at plain O2.
> > > +proc check_effective_target_vect_slp_v4si_store { } {
> > > +    set pattern {add new stmt: MEM <vector\(4\) int>}
> > > +    set macro "TEST_V4SI"
> > > +    return [check_cached_effective_target vect_slp_v4si_store {
> > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > > +}
> > > +
> > >  # Return 1 if we can align stack data to the preferred vector alignment.
> > >
> > >  proc check_effective_target_vect_align_stack_vars { } {
> > > --
> > > 2.18.1
> > >
> > >
>
>
>
> --
> BR,
> Hongtao



-- 
BR,
Hongtao

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] Adjust testcase for O2 vectorization.
  2021-10-21  2:06                                 ` Hongtao Liu
@ 2021-10-21  2:07                                   ` Hongtao Liu
  0 siblings, 0 replies; 29+ messages in thread
From: Hongtao Liu @ 2021-10-21  2:07 UTC (permalink / raw)
  To: Christophe Lyon; +Cc: liuhongt, GCC Patches

On Thu, Oct 21, 2021 at 10:06 AM Hongtao Liu <crazylht@gmail.com> wrote:
>
> On Thu, Oct 21, 2021 at 9:20 AM Hongtao Liu <crazylht@gmail.com> wrote:
> >
> > On Wed, Oct 20, 2021 at 7:34 PM Christophe Lyon via Gcc-patches
> > <gcc-patches@gcc.gnu.org> wrote:
> > >
> > > Hi,
> > >
> > >
> > > On Tue, Oct 19, 2021 at 11:03 AM liuhongt via Gcc-patches <
> > > gcc-patches@gcc.gnu.org> wrote:
> > >
> > > > updated patch:
> > > >   1. Add documents in doc/sourcebuild.texi (Effective-Target Keywords).
> > > >   2. Reduce -novec.c testcases to contain only new failed parted which
> > > > is caused by O2 vectorization.
> > > >   3. Add PR in dg-warning comment.
> > > >
> > > > As discussed in [1], this patch add xfail/target selector to those
> > > > testcases, also make a copy of them so that they can be tested w/o
> > > > vectorization.
> > > >
> > > > Newly added xfail/target selectors are used to check the vectorization
> > > > capability of continuous byte/double bytes storage, these scenarios
> > > > are exactly the part of the testcases that regressed after O2
> > > > vectorization.
> > > >
> > > > [1] https://gcc.gnu.org/pipermail/gcc-patches/2021-October/581456.html.
> > > >
> > > > gcc/ChangeLog
> > > >
> > > >         * doc/sourcebuild.texi (Effective-Target Keywords): Document
> > > >         vect_slp_v2qi_store, vect_slp_v4qi_store, vect_slp_v8qi_store,
> > > >         vect_slp_v16qi_store, vect_slp_v2hi_store,
> > > >         vect_slp_v4hi_store, vect_slp_v2si_store, vect_slp_v4si_store.
> > > >
> > > > gcc/testsuite/ChangeLog
> > > >
> > > >         PR middle-end/102722
> > > >         PR middle-end/102697
> > > >         PR middle-end/102462
> > > >         PR middle-end/102706
> > > >         PR middle-end/102744
> > > >         * c-c++-common/Wstringop-overflow-2.c: Adjust testcase with new
> > > >         xfail/target selector.
> > > >         * gcc.dg/Warray-bounds-51.c: Ditto.
> > > >         * gcc.dg/Warray-parameter-3.c: Ditto.
> > > >         * gcc.dg/Wstringop-overflow-14.c: Ditto.
> > > >         * gcc.dg/Wstringop-overflow-21.c: Ditto.
> > > >         * gcc.dg/Wstringop-overflow-68.c: Ditto.
> > > >         * gcc.dg/Wstringop-overflow-76.c: Ditto.
> > > >         * gcc.dg/Warray-bounds-48.c: Ditto.
> > > >         * gcc.dg/Wzero-length-array-bounds-2.c: Ditto.
> > > >
> > >
> > > Some of these adjustments cause regressions on arm / aarch64, the exact
> > > list depends on the target/flags.
> > > See
> > > https://people.linaro.org/~christophe.lyon/cross-validation/gcc/trunk/r12-4525-gf36240f8c835d792f788b6724e272fc0a4a4f26f/report-build-info.html
> > > for more on details on several combinations.
> > >
> > > Can you have a look?
> > Yes.
> Testcase in target-support doesn't match real testcase, .i.e. for v4qi
> vectorization, it's
> char a[4];
> void foo ()
> {
>   a[0] = 0;
>   a[1] = 1;
>   a[2] = 2;
>   a[3] = 3;
> }
>
> vs
>
> typedef struct AC2 { char a[2]; } AC2;
> typedef struct AC4 { char a[4]; } AC4;
> #define Ac4 (AC4){ 0, 1, 2, 3 }
> extern char a2[2];
> extern char a4[4];
> void
> foo ()
> {
>   *(AC4*)a2 = Ac4;
> }
>
> The former can be vectorized by aarch64-linux-gcc, but the latter
> can't be which cause ned FAIL, similar for other XPASS cases.
>
> Guess we need exact match for testcase in target-supports.exp.
If that, those efficient target would be too special to be used by
others, maybe just as a temporary solution, and should be removed
after Martin fixed those regression.
> > >
> > > Christophe
> > >
> > >         * lib/target-supports.exp (check_vect_slp_aligned_store_usage):
> > > >         New function.
> > > >         (check_effective_target_vect_slp_v2qi_store): Ditto.
> > > >         (check_effective_target_vect_slp_v4qi_store): Ditto.
> > > >         (check_effective_target_vect_slp_v8qi_store): Ditto.
> > > >         (check_effective_target_vect_slp_v16qi_store): Ditto.
> > > >         (check_effective_target_vect_slp_v2hi_store): Ditto.
> > > >         (check_effective_target_vect_slp_v4hi_store): Ditto.
> > > >         (check_effective_target_vect_slp_v2si_store): Ditto.
> > > >         (check_effective_target_vect_slp_v4si_store): Ditto.
> > > >         * c-c++-common/Wstringop-overflow-2-novec.c: New test.
> > > >         * gcc.dg/Warray-bounds-51-novec.c: New test.
> > > >         * gcc.dg/Warray-bounds-48-novec.c: New test.
> > > >         * gcc.dg/Warray-parameter-3-novec.c: New test.
> > > >         * gcc.dg/Wstringop-overflow-14-novec.c: New test.
> > > >         * gcc.dg/Wstringop-overflow-21-novec.c: New test.
> > > >         * gcc.dg/Wstringop-overflow-76-novec.c: New test.
> > > >         * gcc.dg/Wzero-length-array-bounds-2-novec.c: New test.
> > > > ---
> > > >  gcc/doc/sourcebuild.texi                      |  32 ++
> > > >  .../c-c++-common/Wstringop-overflow-2-novec.c | 126 ++++++
> > > >  .../c-c++-common/Wstringop-overflow-2.c       |  20 +-
> > > >  gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c | 364 ++++++++++++++++++
> > > >  gcc/testsuite/gcc.dg/Warray-bounds-48.c       |   4 +-
> > > >  gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c |  21 +
> > > >  gcc/testsuite/gcc.dg/Warray-bounds-51.c       |   2 +-
> > > >  .../gcc.dg/Warray-parameter-3-novec.c         |  16 +
> > > >  gcc/testsuite/gcc.dg/Warray-parameter-3.c     |   2 +-
> > > >  .../gcc.dg/Wstringop-overflow-14-novec.c      |  16 +
> > > >  gcc/testsuite/gcc.dg/Wstringop-overflow-14.c  |   4 +-
> > > >  .../gcc.dg/Wstringop-overflow-21-novec.c      |  34 ++
> > > >  gcc/testsuite/gcc.dg/Wstringop-overflow-21.c  |   8 +-
> > > >  gcc/testsuite/gcc.dg/Wstringop-overflow-68.c  |  17 +-
> > > >  .../gcc.dg/Wstringop-overflow-76-novec.c      |  88 +++++
> > > >  gcc/testsuite/gcc.dg/Wstringop-overflow-76.c  |  18 +-
> > > >  .../Wzero-length-array-bounds-2-novec.c       |  45 +++
> > > >  .../gcc.dg/Wzero-length-array-bounds-2.c      |   2 +-
> > > >  gcc/testsuite/lib/target-supports.exp         | 182 +++++++++
> > > >  19 files changed, 967 insertions(+), 34 deletions(-)
> > > >  create mode 100644 gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> > > >  create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> > > >  create mode 100644 gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> > > >  create mode 100644 gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> > > >  create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> > > >  create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> > > >  create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> > > >  create mode 100644
> > > > gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
> > > >
> > > > diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
> > > > index b1fffd5e90f..6a165767630 100644
> > > > --- a/gcc/doc/sourcebuild.texi
> > > > +++ b/gcc/doc/sourcebuild.texi
> > > > @@ -1845,6 +1845,38 @@ Target supports loop vectorization with partial
> > > > vectors and
> > > >  @item vect_partial_vectors
> > > >  Target supports loop vectorization with partial vectors and
> > > >  @code{vect-partial-vector-usage} is nonzero.
> > > > +
> > > > +@item vect_slp_v2qi_store
> > > > +Target supports vectorization of 2-byte char stores with 2-byte aligned
> > > > +address at plain @option{-O2}.
> > > > +
> > > > +@item vect_slp_v4qi_store
> > > > +Target supports vectorization of 4-byte char stores with 4-byte aligned
> > > > +address at plain @option{-O2}.
> > > > +
> > > > +@item vect_slp_v8qi_store
> > > > +Target supports vectorization of 8-byte char stores with 8-byte aligned
> > > > +address at plain @option{-O2}.
> > > > +
> > > > +@item vect_slp_v16qi_store
> > > > +Target supports vectorization of 16-byte char stores with 16-byte aligned
> > > > +address at plain @option{-O2}.
> > > > +
> > > > +@item vect_slp_v2hi_store
> > > > +Target supports vectorization of 4-byte short stores with 4-byte aligned
> > > > +address at plain @option{-O2}.
> > > > +
> > > > +@item vect_slp_v4hi_store
> > > > +Target supports vectorization of 8-byte short stores with 8-byte aligned
> > > > +address at plain @option{-O2}.
> > > > +
> > > > +@item vect_slp_v2si_store
> > > > +Target supports vectorization of 8-byte int stores with 8-byte aligned
> > > > +address at plain @option{-O2}.
> > > > +
> > > > +@item vect_slp_v4si_store
> > > > +Target supports vectorization of 16-byte int stores with 16-byte aligned
> > > > +address at plain @option{-O2}.
> > > >  @end table
> > > >
> > > >  @subsubsection Thread Local Storage attributes
> > > > diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> > > > b/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> > > > new file mode 100644
> > > > index 00000000000..3c34ad35a5d
> > > > --- /dev/null
> > > > +++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2-novec.c
> > > > @@ -0,0 +1,126 @@
> > > > +/* PR middle-end/91458 - inconsistent warning for writing past the end
> > > > +   of an array member
> > > > +   { dg-do compile }
> > > > +   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds
> > > > -fno-ipa-icf" } */
> > > > +
> > > > +void sink (void*);
> > > > +
> > > > +// Exercise trailing one-element array members.
> > > > +
> > > > +struct A1
> > > > +{
> > > > +  char n;
> > > > +  char a[1];                    // { dg-message "destination object"
> > > > "note" }
> > > > +};
> > > > +
> > > > +// Verify warning for access to a definition with an initializer that
> > > > doesn't
> > > > +// initialize the one-element array member.
> > > > +struct A1 a1__ = { 0 };
> > > > +
> > > > +void ga1__ (void)
> > > > +{
> > > > +  a1__.a[0] = 0;
> > > > +  a1__.a[1] = 1;                 // { dg-warning
> > > > "\\\[-Wstringop-overflow" }
> > > > +  a1__.a[2] = 2;                 // { dg-warning
> > > > "\\\[-Wstringop-overflow" }
> > > > +
> > > > +  struct A1 a = { 1 };
> > > > +  a.a[0] = 0;
> > > > +  a.a[1] = 1;                    // { dg-warning
> > > > "\\\[-Wstringop-overflow" }
> > > > +  a.a[2] = 2;                    // { dg-warning
> > > > "\\\[-Wstringop-overflow" }
> > > > +  sink (&a);
> > > > +}
> > > > +
> > > > +// Verify warning for access to a definition with an initializer that
> > > > +// initializes the one-element array member to empty.
> > > > +struct A1 a1_0 = { 0, { } };
> > > > +
> > > > +void ga1_0_ (void)
> > > > +{
> > > > +  a1_0.a[0] = 0;
> > > > +  a1_0.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +  a1_0.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +
> > > > +  struct A1 a = { 1, { } };
> > > > +  a.a[0] = 0;
> > > > +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +  sink (&a);
> > > > +}
> > > > +
> > > > +// Verify warning for access to a definition with an initializer that
> > > > +// initializes the one-element array member.
> > > > +struct A1 a1_1 = { 0, { 1 } };
> > > > +
> > > > +void ga1_1 (void)
> > > > +{
> > > > +  a1_1.a[0] = 0;
> > > > +  a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +  a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +
> > > > +  struct A1 a = { 0, { 1 } };
> > > > +  a.a[0] = 0;
> > > > +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +  sink (&a);
> > > > +}
> > > > +
> > > > +// Exercise interior one-element array members (verify they're not
> > > > +// treated as trailing.
> > > > +
> > > > +struct A1i
> > > > +{
> > > > +  char n;
> > > > +  char a[1];                    // { dg-message "destination object" }
> > > > +  char x;
> > > > +};
> > > > +
> > > > +// Verify warning for access to a definition with an initializer that
> > > > doesn't
> > > > +// initialize the one-element array member.
> > > > +struct A1i a1i__ = { 0 };
> > > > +
> > > > +void ga1i__ (void)
> > > > +{
> > > > +  a1i__.a[0] = 0;
> > > > +  a1i__.a[1] = 1;                // { dg-warning
> > > > "\\\[-Wstringop-overflow" }
> > > > +  a1i__.a[2] = 2;                // { dg-warning
> > > > "\\\[-Wstringop-overflow" }
> > > > +
> > > > +  struct A1i a = { 0 };
> > > > +  a.a[0] = 0;
> > > > +  a.a[1] = 1;                    // { dg-warning
> > > > "\\\[-Wstringop-overflow" }
> > > > +  a.a[2] = 2;                    // { dg-warning
> > > > "\\\[-Wstringop-overflow" }
> > > > +  sink (&a);
> > > > +}
> > > > +
> > > > +// Verify warning for access to a definition with an initializer that
> > > > +// initializes the one-element array member to empty.
> > > > +struct A1 a1i_0 = { 0, { } };
> > > > +
> > > > +void ga1i_0_ (void)
> > > > +{
> > > > +  a1i_0.a[0] = 0;
> > > > +  a1i_0.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +  a1i_0.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +
> > > > +  struct A1 a = { 0, { } };
> > > > +  a.a[0] = 0;
> > > > +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +  sink (&a);
> > > > +}
> > > > +
> > > > +// Verify warning for access to a definition with an initializer that
> > > > +// initializes the one-element array member.
> > > > +struct A1 a1i_1 = { 0, { 1 } };
> > > > +
> > > > +void ga1i_1 (void)
> > > > +{
> > > > +  a1i_1.a[0] = 0;
> > > > +  a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +  a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +
> > > > +  struct A1 a = { 0, { 1 } };
> > > > +  a.a[0] = 1;
> > > > +  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > +  sink (&a);
> > > > +}
> > > > diff --git a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> > > > b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> > > > index 7d29b5f48c7..ca38bda73f5 100644
> > > > --- a/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> > > > +++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c
> > > > @@ -190,7 +190,7 @@ void ga1__ (void)
> > > >    struct A1 a = { 1 };
> > > >    a.a[0] = 0;
> > > >    a.a[1] = 1;                    // { dg-warning
> > > > "\\\[-Wstringop-overflow" }
> > > > -  a.a[2] = 2;                    // { dg-warning
> > > > "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > > +  a.a[2] = 2;                    // { dg-warning
> > > > "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store } } }
> > > >    sink (&a);
> > > >  }
> > > >
> > > > @@ -207,7 +207,7 @@ void ga1_0_ (void)
> > > >    struct A1 a = { 1, { } };
> > > >    a.a[0] = 0;
> > > >    a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > -  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "" { xfail { i?86-*-* x86_64-*-* } } }
> > > > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "pr102462" { xfail { vect_slp_v2qi_store } } }
> > > >    sink (&a);
> > > >  }
> > > >
> > > > @@ -221,10 +221,10 @@ void ga1_1 (void)
> > > >    a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > >    a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > >
> > > > -  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "" { target { i?86-*-* x86_64-*-* } } }
> > > > +  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "pr102706" { target { vect_slp_v4qi_store } } }
> > > >    a.a[0] = 0;
> > > > -  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "" { xfail { i?86-*-* x86_64-*-* } } }
> > > > -  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "" { xfail { i?86-*-* x86_64-*-* } } }
> > > > +  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "" { xfail { vect_slp_v4qi_store } } }
> > > > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "" { xfail { vect_slp_v4qi_store } } }
> > > >    sink (&a);
> > > >  }
> > > >
> > > > @@ -289,7 +289,7 @@ void ga1i__ (void)
> > > >    struct A1i a = { 0 };
> > > >    a.a[0] = 0;
> > > >    a.a[1] = 1;                    // { dg-warning
> > > > "\\\[-Wstringop-overflow" }
> > > > -  a.a[2] = 2;                    // { dg-warning
> > > > "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > > +  a.a[2] = 2;                    // { dg-warning
> > > > "\\\[-Wstringop-overflow" "pr102462" { xfail { vect_slp_v2qi_store } } }
> > > >    sink (&a);
> > > >  }
> > > >
> > > > @@ -306,7 +306,7 @@ void ga1i_0_ (void)
> > > >    struct A1 a = { 0, { } };
> > > >    a.a[0] = 0;
> > > >    a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > > -  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "" { xfail { i?86-*-* x86_64-*-* } } }
> > > > +  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "pr102462" { xfail { vect_slp_v2qi_store } } }
> > > >    sink (&a);
> > > >  }
> > > >
> > > > @@ -320,10 +320,10 @@ void ga1i_1 (void)
> > > >    a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > >    a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow"
> > > > }
> > > >
> > > > -  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "" { target { i?86-*-* x86_64-*-* } } }
> > > > +  struct A1 a = { 0, { 1 } };   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "pr102462" { target { vect_slp_v4qi_store } } }
> > > >    a.a[0] = 1;
> > > > -  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "" { xfail { i?86-*-* x86_64-*-* } } }
> > > > -  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "" { xfail { i?86-*-* x86_64-*-* } } }
> > > > +  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "pr102462" { xfail { vect_slp_v4qi_store } } }
> > > > +  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow"
> > > > "pr102462" { xfail { vect_slp_v4qi_store } } }
> > > >    sink (&a);
> > > >  }
> > > >
> > > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> > > > b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> > > > new file mode 100644
> > > > index 00000000000..da179a2c0f5
> > > > --- /dev/null
> > > > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c
> > > > @@ -0,0 +1,364 @@
> > > > +/* PR middle-end/91647 - missing -Warray-bounds accessing a zero-length
> > > > array
> > > > +   of a declared object
> > > > +   { dg-do "compile" }
> > > > +   { dg-options "-O2 -Wall -fno-tree-vectorize" }
> > > > +   { dg-require-effective-target alloca } */
> > > > +
> > > > +typedef __INT16_TYPE__ int16_t;
> > > > +typedef __INT32_TYPE__ int32_t;
> > > > +
> > > > +void sink (void*);
> > > > +
> > > > +/* Exercise a true flexible member.  */
> > > > +
> > > > +struct AX
> > > > +{
> > > > +  int32_t n;
> > > > +  int16_t ax[];     // { dg-message "while referencing 'ax'" "member" }
> > > > +};
> > > > +
> > > > +static void warn_ax_local (struct AX *p)
> > > > +{
> > > > +  p->ax[0] = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->ax[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > +
> > > > +static void nowarn_ax_extern (struct AX *p)
> > > > +{
> > > > +  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
> > > > +}
> > > > +
> > > > +static void warn_ax_local_buf (struct AX *p)
> > > > +{
> > > > +  p->ax[0] = 4; p->ax[1] = 5;
> > > > +
> > > > +  p->ax[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->ax[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->ax[4] = 8;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > +
> > > > +static void warn_ax_extern_buf (struct AX *p)
> > > > +{
> > > > +  p->ax[0] = 9; p->ax[1] = 10; p->ax[2] = 11;
> > > > +
> > > > +  p->ax[3] = 12;    // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->ax[4] = 13;    // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->ax[5] = 14;    // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > +
> > > > +static void nowarn_ax_extern_bufx (struct AX *p)
> > > > +{
> > > > +  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
> > > > +}
> > > > +
> > > > +static void nowarn_ax_ref (struct AX *p)
> > > > +{
> > > > +  p->ax[0] = 0; p->ax[99] = 99; p->ax[999] = 999; p->ax[9999] = 9999;
> > > > +}
> > > > +
> > > > +void test_ax (struct AX *p, unsigned n)
> > > > +{
> > > > +  {
> > > > +    struct AX sax;  // { dg-message "defined here" "struct definition" }
> > > > +    warn_ax_local (&sax);
> > > > +    sink (&sax);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    extern
> > > > +      struct AX xsax;
> > > > +    nowarn_ax_extern (&xsax);
> > > > +    sink (&xsax);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
> > > > +    char ax_buf_p2[sizeof (struct AX) + 2 * sizeof (int16_t)];
> > > > +    warn_ax_local_buf ((struct AX*) ax_buf_p2);
> > > > +    sink (ax_buf_p2);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    /* Verify out-of-bounds access to the extern BUF with a known
> > > > +       bound is diagnosed.  */
> > > > +    extern char ax_buf_p3[sizeof (struct AX) + 3 * sizeof (int16_t)];
> > > > +    warn_ax_extern_buf ((struct AX*) ax_buf_p3);
> > > > +    sink (ax_buf_p3);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    /* Verify that accesses to BUFX with an unknown bound are not
> > > > +       diagnosed.  */
> > > > +    extern char bufx[];
> > > > +    nowarn_ax_extern_bufx ((struct AX*) bufx);
> > > > +    sink (bufx);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    /* Verify that accesses to BUFN with a runtime bound are not
> > > > +       diagnosed.  */
> > > > +    char bufn[n];
> > > > +    nowarn_ax_extern_bufx ((struct AX*) bufn);
> > > > +    sink (bufn);
> > > > +  }
> > > > +
> > > > +  nowarn_ax_ref (p);
> > > > +}
> > > > +
> > > > +
> > > > +/* Exercise a zero-length trailing member array.  It's the same as above
> > > > +   except that extern declarations with no definitions are considered to
> > > > +   have zero elements (they can't be initialized to have any).  */
> > > > +
> > > > +struct A0
> > > > +{
> > > > +  int32_t n;
> > > > +  int16_t a0[0];    // { dg-message "while referencing 'a0'" "member" }
> > > > +};
> > > > +
> > > > +static void warn_a0_local (struct A0 *p)
> > > > +{
> > > > +  p->a0[0] = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->a0[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > +
> > > > +static void warn_a0_extern (struct A0 *p)
> > > > +{
> > > > +  p->a0[0] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->a0[1] = 3;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > +
> > > > +static void warn_a0_local_buf (struct A0 *p)
> > > > +{
> > > > +  p->a0[0] = 4; p->a0[1] = 5;
> > > > +
> > > > +  p->a0[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->a0[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->a0[4] = 8;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > +
> > > > +static void warn_a0_extern_buf (struct A0 *p)
> > > > +{
> > > > +  p->a0[0] = 9; p->a0[1] = 10; p->a0[2] = 11;
> > > > +
> > > > +  p->a0[3] = 12;    // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->a0[4] = 13;    // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->a0[5] = 14;    // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > +
> > > > +static void nowarn_a0_extern_bufx (struct A0 *p)
> > > > +{
> > > > +  p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
> > > > +}
> > > > +
> > > > +static void nowarn_a0_ref (struct A0 *p)
> > > > +{
> > > > +  p->a0[0] = 0; p->a0[99] = 99; p->a0[999] = 999; p->a0[9999] = 9999;
> > > > +}
> > > > +
> > > > +void test_a0 (struct A0 *p, unsigned n)
> > > > +{
> > > > +  {
> > > > +    struct A0 sa0;  // { dg-message "defined here" "struct definition" }
> > > > +    warn_a0_local (&sa0);
> > > > +    sink (&sa0);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    extern
> > > > +      struct A0 xsa0;  // { dg-message "defined here" "struct definition"
> > > > }
> > > > +    warn_a0_extern (&xsa0);
> > > > +    sink (&xsa0);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
> > > > +    char a0_buf_p2[sizeof (struct A0) + 2 * sizeof (int16_t)];
> > > > +    warn_a0_local_buf ((struct A0*) a0_buf_p2);
> > > > +    sink (a0_buf_p2);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    /* Verify out-of-bounds access to the extern BUF with a known
> > > > +       bound is diagnosed.  */
> > > > +    extern char a0_buf_p3[sizeof (struct A0) + 3 * sizeof (int16_t)];
> > > > +    warn_a0_extern_buf ((struct A0*) a0_buf_p3);
> > > > +    sink (a0_buf_p3);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    /* Verify that accesses to BUFX with an unknown bound are not
> > > > +       diagnosed.  */
> > > > +    extern char bufx[];
> > > > +    nowarn_a0_extern_bufx ((struct A0*) bufx);
> > > > +    sink (bufx);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    /* Verify that accesses to BUFN with a runtime bound are not
> > > > +       diagnosed.  */
> > > > +    char bufn[n];
> > > > +    nowarn_a0_extern_bufx ((struct A0*) bufn);
> > > > +    sink (bufn);
> > > > +  }
> > > > +
> > > > +  nowarn_a0_ref (p);
> > > > +}
> > > > +
> > > > +
> > > > +/* Exercise a one-element trailing member array.  It's the same as above
> > > > +   except that it has exactly one element.  */
> > > > +
> > > > +struct A1
> > > > +{
> > > > +  int32_t n;
> > > > +  int16_t a1[1];    // { dg-message "while referencing 'a1'" }
> > > > +};
> > > > +
> > > > +static void warn_a1_local_noinit (struct A1 *p)
> > > > +{
> > > > +  p->a1[0] = 0;
> > > > +  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > +
> > > > +static void warn_a1_extern (struct A1 *p)
> > > > +{
> > > > +  p->a1[0] = 0;
> > > > +  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > +
> > > > +static void warn_a1_init (struct A1 *p)
> > > > +{
> > > > +  p->a1[0] = 0;
> > > > +  p->a1[1] = 1;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->a1[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > +
> > > > +static void warn_a1_local_buf (struct A1 *p)
> > > > +{
> > > > +  p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3;
> > > > +
> > > > +  p->a1[4] = 4;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > +
> > > > +static void warn_a1_extern_buf (struct A1 *p)
> > > > +{
> > > > +  p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3; p->a1[4] = 4;
> > > > +
> > > > +  p->a1[5] = 5;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > +
> > > > +static void nowarn_a1_extern_bufx (struct A1 *p)
> > > > +{
> > > > +  p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
> > > > +}
> > > > +
> > > > +static void nowarn_a1_ref (struct A1 *p)
> > > > +{
> > > > +  p->a1[0] = 0; p->a1[99] = 99; p->a1[999] = 999; p->a1[9999] = 9999;
> > > > +}
> > > > +
> > > > +void test_a1 (struct A1 *p, unsigned n)
> > > > +{
> > > > +  {
> > > > +    struct A1 a1;
> > > > +    warn_a1_local_noinit (&a1);
> > > > +    sink (&a1);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    extern struct A1 a1x;
> > > > +    warn_a1_extern (&a1x);
> > > > +    sink (&a1x);
> > > > +}
> > > > +  {
> > > > +    struct A1 a1 = { 0, { 1 } };
> > > > +    warn_a1_init (&a1);
> > > > +    sink (&a1);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    /* Verify out-of-bounds access to the local BUF is diagnosed.  */
> > > > +    char buf_p2[sizeof (struct A1) + 2 * sizeof (int16_t)];
> > > > +    warn_a1_local_buf ((struct A1*) buf_p2);
> > > > +    sink (buf_p2);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    /* Verify out-of-bounds access to the extern BUF with a known
> > > > +       bound is diagnosed.  */
> > > > +    extern char a1_buf_p3[sizeof (struct A1) + 3 * sizeof (int16_t)];
> > > > +    warn_a1_extern_buf ((struct A1*) a1_buf_p3);
> > > > +    sink (a1_buf_p3);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    /* Verify that accesses to BUFX with an unknown bound are not
> > > > +       diagnosed.  */
> > > > +    extern char bufx[];
> > > > +    nowarn_a1_extern_bufx ((struct A1*) bufx);
> > > > +    sink (bufx);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    /* Verify that accesses to BUFN with a runtime bound are not
> > > > +       diagnosed.  */
> > > > +    char bufn[n];
> > > > +    nowarn_a1_extern_bufx ((struct A1*) bufn);
> > > > +    sink (bufn);
> > > > +  }
> > > > +
> > > > +  nowarn_a1_ref (p);
> > > > +}
> > > > +
> > > > +
> > > > +/* Exercise a two-element trailing member array.  It's treated
> > > > +   the same as an interior array member.  */
> > > > +
> > > > +struct A2
> > > > +{
> > > > +  int32_t n;
> > > > +  int16_t a2[2];    // { dg-message "while referencing 'a2'" }
> > > > +};
> > > > +
> > > > +static void warn_a2_noinit (struct A2 *p)
> > > > +{
> > > > +  p->a2[0] = 0; p->a2[1] = 1;
> > > > +
> > > > +  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > +
> > > > +static void warn_a2_init (struct A2 *p)
> > > > +{
> > > > +  p->a2[0] = 0; p->a2[1] = 1;
> > > > +
> > > > +  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->a2[9] = 9;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > +
> > > > +static void warn_a2_ref (struct A2 *p)
> > > > +{
> > > > +  p->a2[0] = 0; p->a2[1] = 1;
> > > > +
> > > > +  p->a2[2] = 2;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->a2[9] = 9;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > +
> > > > +void test_a2 (struct A2 *p)
> > > > +{
> > > > +  {
> > > > +    struct A2 a2;
> > > > +    warn_a2_noinit (&a2);
> > > > +    sink (&a2);
> > > > +  }
> > > > +
> > > > +  {
> > > > +    struct A2 a2 = { 0, { 1, 2 } };
> > > > +    warn_a2_init (&a2);
> > > > +    sink (&a2);
> > > > +  }
> > > > +
> > > > +  warn_a2_ref (p);
> > > > +}
> > > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> > > > b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> > > > index 13373d1e99e..19b7634c063 100644
> > > > --- a/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> > > > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
> > > > @@ -30,7 +30,7 @@ static void nowarn_ax_extern (struct AX *p)
> > > >
> > > >  static void warn_ax_local_buf (struct AX *p)
> > > >  {
> > > > -  p->ax[0] = 4; p->ax[1] = 5;
> > > > +  p->ax[0] = 4; p->ax[1] = 5;  // { dg-warning "\\\[-Wstringop-overflow"
> > > > "pr102706" { target { vect_slp_v2hi_store &&  { ! vect_slp_v4hi_store } } }
> > > > }
> > > >
> > > >    p->ax[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> > > >    p->ax[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> > > > @@ -130,7 +130,7 @@ static void warn_a0_extern (struct A0 *p)
> > > >
> > > >  static void warn_a0_local_buf (struct A0 *p)
> > > >  {
> > > > -  p->a0[0] = 4; p->a0[1] = 5;
> > > > +  p->a0[0] = 4; p->a0[1] = 5;  // { dg-warning "\\\[-Wstringop-overflow"
> > > > "pr102706" { target { vect_slp_v2hi_store && { ! vect_slp_v4hi_store } } } }
> > > >
> > > >    p->a0[2] = 6;     // { dg-warning "\\\[-Warray-bounds" }
> > > >    p->a0[3] = 7;     // { dg-warning "\\\[-Warray-bounds" }
> > > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> > > > b/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> > > > new file mode 100644
> > > > index 00000000000..ef8056d9b7f
> > > > --- /dev/null
> > > > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-51-novec.c
> > > > @@ -0,0 +1,21 @@
> > > > +/* PR middle-end/92333 - missing variable name referencing VLA in warnings
> > > > +   PR middle-end/82608 - missing -Warray-bounds on an out-of-bounds VLA
> > > > index
> > > > +   { dg-do compile }
> > > > +   { dg-options "-O2 -Wall -fno-tree-vectorize" }  */
> > > > +
> > > > +void sink (void*);
> > > > +
> > > > +void test_struct_char_vla_location (void)
> > > > +{
> > > > +  unsigned nelts = 7;
> > > > +
> > > > +  struct {
> > > > +    char cvla[nelts]; // { dg-message "declared here|while referencing" }
> > > > +  } s;
> > > > +
> > > > +  s.cvla[0] = __LINE__;
> > > > +  s.cvla[nelts - 1] = 0;
> > > > +  s.cvla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
> > > > +
> > > > +  sink (&s);
> > > > +}
> > > > diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> > > > b/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> > > > index de60d87ab95..8b589f38191 100644
> > > > --- a/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> > > > +++ b/gcc/testsuite/gcc.dg/Warray-bounds-51.c
> > > > @@ -39,7 +39,7 @@ void test_struct_char_vla_location (void)
> > > >    } s;
> > > >
> > > >    s.cvla[0] = __LINE__;
> > > > -  s.cvla[nelts - 1] = 0; // { dg-warning "\\\[-Wstringop-overflow" "" {
> > > > target { i?86-*-* x86_64-*-* } } }
> > > > +  s.cvla[nelts - 1] = 0; // { dg-warning "\\\[-Wstringop-overflow"
> > > > "pr102706" { target { vect_slp_v2qi_store } } }
> > > >    s.cvla[nelts] = 0;  // { dg-warning "\\\[-Warray-bounds" }
> > > >
> > > >    sink (&s);
> > > > diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> > > > b/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> > > > new file mode 100644
> > > > index 00000000000..5089d555392
> > > > --- /dev/null
> > > > +++ b/gcc/testsuite/gcc.dg/Warray-parameter-3-novec.c
> > > > @@ -0,0 +1,16 @@
> > > > +/* PR c/50584 - No warning for passing small array to C99 static array
> > > > +   declarator
> > > > +   { dg-do compile }
> > > > +   { dg-options "-Wall -Warray-parameter=1" } */
> > > > +
> > > > +/* Also verify that -Warray-bounds doesn't trigger for ordinary array
> > > > +   parameters...  */
> > > > +#pragma GCC optimize ("2,no-tree-vectorize")
> > > > +
> > > > +/* ...but does for static arrays.  */
> > > > +__attribute__ ((noipa)) void
> > > > +gcas3 (char a[static 3])
> > > > +{
> > > > +  a[0] = 0; a[1] = 1; a[2] = 2;
> > > > +  a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
> > > > +}
> > > > diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> > > > b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> > > > index e8a269c85c6..b6ed8daf51c 100644
> > > > --- a/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> > > > +++ b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
> > > > @@ -77,7 +77,7 @@ gia3 (int a[3])
> > > >  __attribute__ ((noipa)) void
> > > >  gcas3 (char a[static 3])
> > > >  {
> > > > -  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow"
> > > > "" { target { i?86-*-* x86_64-*-* } } }
> > > > +  a[0] = 0; a[1] = 1; a[2] = 2; // { dg-warning "\\\[-Wstringop-overflow"
> > > > "pr102706" { target { vect_slp_v4qi_store } } }
> > > >    a[3] = 3;                   // { dg-warning "\\\[-Warray-bounds" }
> > > >  }
> > > >
> > > > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> > > > b/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> > > > new file mode 100644
> > > > index 00000000000..de39eaaeb95
> > > > --- /dev/null
> > > > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-14-novec.c
> > > > @@ -0,0 +1,16 @@
> > > > +/* Test to verify that past-the-end multibyte writes via lvalues of wider
> > > > +   types than char are diagnosed.
> > > > +   { dg-do compile }
> > > > +   { dg-require-effective-target int32plus }
> > > > +   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds" }  */
> > > > +
> > > > +typedef __INT16_TYPE__  int16_t;
> > > > +
> > > > +char a4[4], a8[8], a16[16];
> > > > +
> > > > +void test_int16 (void)
> > > > +{
> > > > +  char *p = a4 + 1;
> > > > +  *(int16_t*)p = 0;
> > > > +  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a
> > > > region of size 1" }
> > > > +}
> > > > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> > > > b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> > > > index 7683084e46e..c4a3f05d883 100644
> > > > --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> > > > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
> > > > @@ -36,8 +36,8 @@ void test_memcpy_cond (int i)
> > > >  void test_int16 (void)
> > > >  {
> > > >    char *p = a4 + 1;
> > > > -  *(int16_t*)p = 0;    // { dg-warning "writing 4 bytes into a region of
> > > > size 3" "" { target { i?86-*-* x86_64-*-* } } }
> > > > -  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a
> > > > region of size 1" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > > +  *(int16_t*)p = 0;    // { dg-warning "writing 4 bytes into a region of
> > > > size 3" "pr102706" { target { vect_slp_v2hi_store } } }
> > > > +  *(int16_t*)(p + 2) = 0;   // { dg-warning "writing 2 bytes into a
> > > > region of size 1" "pr102706" { xfail { vect_slp_v2hi_store } } }
> > > >  }
> > > >
> > > >
> > > > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> > > > b/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> > > > new file mode 100644
> > > > index 00000000000..6f83548e902
> > > > --- /dev/null
> > > > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-21-novec.c
> > > > @@ -0,0 +1,34 @@
> > > > +/* PR middle-end/92312 - bogus -Wstringop-overflow storing into a trailing
> > > > +   array backed by larger buffer
> > > > +   { dg-do compile }
> > > > +   { dg-options "-O2 -fno-tree-vectorize -Wall -Wno-array-bounds" } */
> > > > +
> > > > +struct S0 { char a, b[0]; };
> > > > +
> > > > +void sink (void*);
> > > > +
> > > > +void test_store_zero_length (int i)
> > > > +{
> > > > +  char a[3];
> > > > +  struct S0 *p = (struct S0*)a;
> > > > +  p->a = 0;
> > > > +  p->b[0] = 0;
> > > > +  p->b[1] = 1;                      // { dg-bogus
> > > > "\\\[-Wstringop-overflow" }
> > > > +  p->b[2] = 2;                      // { dg-warning
> > > > "\\\[-Wstringop-overflow" }
> > > > +  p->b[i] = 2;
> > > > +  sink (p);
> > > > +}
> > > > +
> > > > +struct Sx { char a, b[]; };
> > > > +
> > > > +void test_store_flexarray (int i)
> > > > +{
> > > > +  char a[3];
> > > > +  struct Sx *p = (struct Sx*)a;
> > > > +  p->a = 0;
> > > > +  p->b[0] = 0;
> > > > +  p->b[1] = 1;                      // { dg-bogus
> > > > "\\\[-Wstringop-overflow" }
> > > > +  p->b[2] = 1;                      // { dg-warning
> > > > "\\\[-Wstringop-overflow" }
> > > > +  p->b[i] = 2;
> > > > +  sink (p);
> > > > +}
> > > > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> > > > b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> > > > index d88bde9c740..3fccfc9a798 100644
> > > > --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> > > > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-21.c
> > > > @@ -23,10 +23,10 @@ void test_store_zero_length (int i)
> > > >  {
> > > >    char a[3];
> > > >    struct S0 *p = (struct S0*)a;
> > > > -  p->a = 0;                         // { dg-warning
> > > > "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> > > > +  p->a = 0;                         // { dg-warning
> > > > "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v4qi_store } } }
> > > >    p->b[0] = 0;
> > > >    p->b[1] = 1;                      // { dg-bogus
> > > > "\\\[-Wstringop-overflow" }
> > > > -  p->b[2] = 2;                      // { dg-warning
> > > > "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > > +  p->b[2] = 2;                      // { dg-warning
> > > > "\\\[-Wstringop-overflow" "pr102706" { xfail { vect_slp_v4qi_store } } }
> > > >    p->b[i] = 2;
> > > >    sink (p);
> > > >  }
> > > > @@ -50,10 +50,10 @@ void test_store_flexarray (int i)
> > > >  {
> > > >    char a[3];
> > > >    struct Sx *p = (struct Sx*)a;
> > > > -  p->a = 0;                         // { dg-warning
> > > > "\\\[-Wstringop-overflow" "" { target { i?86-*-* x86_64-*-* } } }
> > > > +  p->a = 0;                         // { dg-warning
> > > > "\\\[-Wstringop-overflow" "pr102706" { target { vect_slp_v4qi_store } } }
> > > >    p->b[0] = 0;
> > > >    p->b[1] = 1;                      // { dg-bogus
> > > > "\\\[-Wstringop-overflow" }
> > > > -  p->b[2] = 1;                      // { dg-warning
> > > > "\\\[-Wstringop-overflow" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > > +  p->b[2] = 1;                      // { dg-warning
> > > > "\\\[-Wstringop-overflow" "pr102706" { xfail { vect_slp_v4qi_store } } }
> > > >    p->b[i] = 2;
> > > >    sink (p);
> > > >  }
> > > > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> > > > b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> > > > index 09df0004991..04e91afb8bc 100644
> > > > --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> > > > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-68.c
> > > > @@ -58,11 +58,18 @@ void warn_comp_lit_zero (void)
> > > >  void warn_comp_lit (void)
> > > >  {
> > > >    *(AC2*)a1 = Ac2;      // { dg-warning "writing 2 bytes into a region of
> > > > size 1" "pr101475" { xfail *-*-* } }
> > > > -  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> > > > size 2" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> > > > -  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> > > > size 3" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> > > > -  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> > > > size 4" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> > > > -  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> > > > size 7" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> > > > -  *(AC16*)a15 = Ac16;   // { dg-warning "writing 16 bytes into a region
> > > > of size 15" "pr101475" { xfail { ! { i?86-*-* x86_64-*-* } } } }
> > > > +  // After vectorization, below codes are optimized to
> > > > +  // MEM <vector(4) char> [(char *)&a2] = { 0, 1, 2, 3 };
> > > > +  // MEM <vector(4) char> [(char *)&a3] = { 0, 1, 2, 3 };
> > > > +  // MEM <vector(8) char> [(char *)&a4] = { 0, 1, 2, 3, 4, 5, 6, 7 };
> > > > +  // MEM <vector(8) char> [(char *)&a7] = { 0, 1, 2, 3, 4, 5, 6, 7 };
> > > > +  // MEM <vector(16) char> [(char *)&a15] = { 0, 1, 2, 3, 4, 5, 6, 7, 8,
> > > > 9, 10, 11, 12, 13, 14, 15 };
> > > > +  // and warning should be expected, refer to PR102722.
> > > > +  *(AC4*)a2 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> > > > size 2" "pr101475" { xfail { ! { vect_slp_v4qi_store } } } }
> > > > +  *(AC4*)a3 = Ac4;      // { dg-warning "writing 4 bytes into a region of
> > > > size 3" "pr101475" { xfail { ! { vect_slp_v4qi_store } } } }
> > > > +  *(AC8*)a4 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> > > > size 4" "pr101475" { xfail { ! { vect_slp_v8qi_store } } } }
> > > > +  *(AC8*)a7 = Ac8;      // { dg-warning "writing 8 bytes into a region of
> > > > size 7" "pr101475" { xfail { ! { vect_slp_v8qi_store } } } }
> > > > +  *(AC16*)a15 = Ac16;   // { dg-warning "writing 16 bytes into a region
> > > > of size 15" "pr101475" { xfail { ! { vect_slp_v16qi_store } } } }
> > > >  }
> > > >
> > > >  void warn_aggr_decl (void)
> > > > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> > > > b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> > > > new file mode 100644
> > > > index 00000000000..71c643b62fb
> > > > --- /dev/null
> > > > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76-novec.c
> > > > @@ -0,0 +1,88 @@
> > > > +/* Verify warnings and notes for MAX_EXPRs involving either pointers
> > > > +   to distinct objects or one to a known object and the other to
> > > > +   an unknown one.  Unlike for the same object, for unrelated objects
> > > > +   the expected warnings and notes are the same as for MIN_EXPR: when
> > > > +   the order of the objects in the address space cannot be determined
> > > > +   the larger of them is assumed to be used.  (This is different for
> > > > +   distinct struct members where the order is given.)
> > > > +   The relational expressions are strictly invalid but that should be
> > > > +   diagnosed by a separate warning.
> > > > +   { dg-do compile }
> > > > +   { dg-options "-O2 -Wno-array-bounds -fno-tree-vectorize" } */
> > > > +
> > > > +#define MAX(p, q) ((p) > (q) ? (p) : (q))
> > > > +
> > > > +/* Verify that even for MAX_EXPR and like for MIN_EXPR, the note points
> > > > +   to the larger of the two objects and mentions the offset into it
> > > > +   (although the offset might be better included in the warning).  */
> > > > +extern char a3[3];
> > > > +extern char a5[5];  // { dg-message "at offset 5 into destination object
> > > > 'a5' of size 5" "note" }
> > > > +
> > > > +void max_a3_a5 (int i)
> > > > +{
> > > > +  char *p = a3 + i;
> > > > +  char *q = a5 + i;
> > > > +
> > > > +  /* The relational expression below is invalid and should be diagnosed
> > > > +     by its own warning independently of -Wstringop-overflow.  */
> > > > +  char *d = MAX (p, q);
> > > > +
> > > > +  d[2] = 0;
> > > > +  d[3] = 0;
> > > > +  d[4] = 0;
> > > > +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > > 0" }
> > > > +}
> > > > +
> > > > +
> > > > +// Same as above but with the larger array as the first MAX_EXPR operand.
> > > > +extern char b4[4];
> > > > +extern char b6[6];  // { dg-message "at offset 6 into destination object
> > > > 'b6' of size 6" "note" }
> > > > +
> > > > +void max_b6_b4 (int i)
> > > > +{
> > > > +  char *p = b6 + i;
> > > > +  char *q = b4 + i;
> > > > +  char *d = MAX (p, q);
> > > > +
> > > > +  d[3] = 0;
> > > > +  d[4] = 0;
> > > > +  d[5] = 0;
> > > > +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > > 0" }
> > > > +}
> > > > +
> > > > +struct A3_5
> > > > +{
> > > > +  char a3[3];  // { dg-message "at offset 3 into destination object 'a3'
> > > > of size 3" "pr??????" { xfail *-*-* } }
> > > > +  char a5[5];  // { dg-message "at offset 5 into destination object 'a5'
> > > > of size 5" "note" }
> > > > +};
> > > > +
> > > > +void max_A3_A5 (int i, struct A3_5 *pa3_5)
> > > > +{
> > > > +  char *p = pa3_5->a3 + i;
> > > > +  char *q = pa3_5->a5 + i;
> > > > +
> > > > +  char *d = MAX (p, q);
> > > > +  d[2] = 0;
> > > > +  d[3] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > > 0" "pr??????" { xfail *-*-* } }
> > > > +  d[4] = 0;
> > > > +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > > 0" }
> > > > +}
> > > > +
> > > > +
> > > > +struct B4_B6
> > > > +{
> > > > +  char b4[4];
> > > > +  char b6[6];       // { dg-message "at offset 6 into destination object
> > > > 'b6' of size 6" "note" }
> > > > +};
> > > > +
> > > > +void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
> > > > +{
> > > > +  char *p = pb4_b6->b6 + i;
> > > > +  char *q = pb4_b6->b4 + i;
> > > > +  char *d = MAX (p, q);
> > > > +
> > > > +  d[3] = 0;
> > > > +  d[4] = 0;
> > > > +  d[5] = 0;
> > > > +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > > 0" }
> > > > +}
> > > > diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> > > > b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> > > > index 0c7b53ccc0b..52467267a04 100644
> > > > --- a/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> > > > +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-76.c
> > > > @@ -27,10 +27,10 @@ void max_a3_a5 (int i)
> > > >       by its own warning independently of -Wstringop-overflow.  */
> > > >    char *d = MAX (p, q);
> > > >
> > > > -  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of
> > > > size 3" "" { target { i?86-*-* x86_64-*-* } } }
> > > > +  d[2] = 0;         // { dg-warning "writing 4 bytes into a region of
> > > > size 3" "pr102706" { target { vect_slp_v4qi_store } } }
> > > >    d[3] = 0;
> > > >    d[4] = 0;
> > > > -  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > > 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > > +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > > 0" "pr102706" { xfail { vect_slp_v4qi_store } } }
> > > >  }
> > > >
> > > >
> > > > @@ -44,10 +44,10 @@ void max_b6_b4 (int i)
> > > >    char *q = b4 + i;
> > > >    char *d = MAX (p, q);
> > > >
> > > > -  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of
> > > > size 3" "" { target { i?86-*-* x86_64-*-* } } }
> > > > +  d[3] = 0;         // { dg-warning "writing 4 bytes into a region of
> > > > size 3" "pr102706" { target { vect_slp_v4qi_store } } }
> > > >    d[4] = 0;
> > > >    d[5] = 0;
> > > > -  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > > 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > > +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > > 0" "pr102706" { xfail { vect_slp_v4qi_store } } }
> > > >  }
> > > >
> > > >
> > > > @@ -82,7 +82,8 @@ void max_d8_p (char *q, int i)
> > > >  struct A3_5
> > > >  {
> > > >    char a3[3];  // { dg-message "at offset 3 into destination object 'a3'
> > > > of size 3" "pr??????" { xfail *-*-* } }
> > > > -  char a5[5];  // { dg-message "at offset 5 into destination object 'a5'
> > > > of size 5" "note" { xfail { i?86-*-* x86_64-*-* } } }
> > > > +  // refer to pr102697 for xfail
> > > > +  char a5[5];  // { dg-message "at offset 5 into destination object 'a5'
> > > > of size 5" "note" { xfail { vect_slp_v4qi_store } } }
> > > >  };
> > > >
> > > >  void max_A3_A5 (int i, struct A3_5 *pa3_5)
> > > > @@ -95,14 +96,15 @@ void max_A3_A5 (int i, struct A3_5 *pa3_5)
> > > >    d[2] = 0;
> > > >    d[3] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > > 0" "pr??????" { xfail *-*-* } }
> > > >    d[4] = 0;
> > > > -  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > > 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > > +  d[5] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > > 0" "pr102697" { xfail { vect_slp_v4qi_store } } }
> > > >  }
> > > >
> > > >
> > > >  struct B4_B6
> > > >  {
> > > >    char b4[4];
> > > > -  char b6[6];       // { dg-message "at offset
> > > > \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6"
> > > > "note" { xfail { i?86-*-* x86_64-*-* } } }
> > > > +  // refer to pr102697 for xfail
> > > > +  char b6[6];       // { dg-message "at offset
> > > > \[^a-zA-Z\n\r\]*6\[^a-zA-Z0-9\]* into destination object 'b6' of size 6"
> > > > "note" { xfail { vect_slp_v4qi_store } } }
> > > >  };
> > > >
> > > >  void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
> > > > @@ -114,7 +116,7 @@ void max_B6_B4 (int i, struct B4_B6 *pb4_b6)
> > > >    d[3] = 0;
> > > >    d[4] = 0;
> > > >    d[5] = 0;
> > > > -  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > > 0" "" { xfail { i?86-*-* x86_64-*-* } } }
> > > > +  d[6] = 0;         // { dg-warning "writing 1 byte into a region of size
> > > > 0" "pr102697" { xfail { vect_slp_v4qi_store } } }
> > > >  }
> > > >
> > > >
> > > > diff --git a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
> > > > b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
> > > > new file mode 100644
> > > > index 00000000000..8e023b7cfa7
> > > > --- /dev/null
> > > > +++ b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2-novec.c
> > > > @@ -0,0 +1,45 @@
> > > > +/* Test to verify that -Wzero-length-bounds and not -Warray-bounds is
> > > > +   issued for accesses to interior zero-length array members that are
> > > > +   within the bounds of the enclosing struct.
> > > > +   { dg-do compile }
> > > > +   { dg-options "-O2 -Wall -fno-tree-vectorize" } */
> > > > +
> > > > +void sink (void*);
> > > > +
> > > > +struct A { int i; };
> > > > +struct B { int j; struct A a[0]; };
> > > > +
> > > > +struct C
> > > > +{
> > > > +  struct B b1;
> > > > +  struct B b2;
> > > > +};
> > > > +
> > > > +char cbuf1[1 * sizeof (struct C)];
> > > > +char cbuf2[2 * sizeof (struct C)] = { };
> > > > +
> > > > +void test_C_global_buf (void)
> > > > +{
> > > > +  struct C *p = (struct C*)&cbuf1;
> > > > +
> > > > +  p->b1.a[-1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->b1.a[ 0].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
> > > > +  p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  sink (p);
> > > > +
> > > > +  p->b2.a[ 0].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->b2.a[ 1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  sink (p);
> > > > +
> > > > +  p = (struct C*)&cbuf2;
> > > > +  p->b1.a[-1].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->b1.a[ 0].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
> > > > +  p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
> > > > +  sink (p);
> > > > +
> > > > +  p->b2.a[ 0].i = 0;
> > > > +  p->b2.a[ 1].i = 0;
> > > > +  p->b2.a[ 2].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  p->b2.a[ 3].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > > +  sink (p);
> > > > +}
> > > > diff --git a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> > > > b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> > > > index 841b2bfa122..b2321495afc 100644
> > > > --- a/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> > > > +++ b/gcc/testsuite/gcc.dg/Wzero-length-array-bounds-2.c
> > > > @@ -87,7 +87,7 @@ void test_C_global_buf (void)
> > > >    p->b1.a[ 1].i = 0;     // { dg-warning "\\\[-Wzero-length-bounds" }
> > > >    sink (p);
> > > >
> > > > -  p->b2.a[ 0].i = 0;
> > > > +  p->b2.a[ 0].i = 0;    // { dg-warning "\\\[-Wstringop-overflow"
> > > > "pr102706" { target { vect_slp_v2si_store &&  { ! vect_slp_v4si_store } } }
> > > > }
> > > >    p->b2.a[ 1].i = 0;
> > > >    p->b2.a[ 2].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > >    p->b2.a[ 3].i = 0;     // { dg-warning "\\\[-Warray-bounds" }
> > > > diff --git a/gcc/testsuite/lib/target-supports.exp
> > > > b/gcc/testsuite/lib/target-supports.exp
> > > > index 9ebca7ac007..1c8b1ebb86e 100644
> > > > --- a/gcc/testsuite/lib/target-supports.exp
> > > > +++ b/gcc/testsuite/lib/target-supports.exp
> > > > @@ -7580,6 +7580,188 @@ proc
> > > > check_effective_target_vect_element_align_preferred { } {
> > > >                    && [check_effective_target_vect_variable_length] }]
> > > >  }
> > > >
> > > > +# Return true if vectorization of v2qi/v4qi/v8qi/v16qi/v2hi store is
> > > > enabed.
> > > > +# Return zero if the desirable pattern isn't found.
> > > > +# It's used by Warray-bounds/Wstringop-overflow testcases which are
> > > > +# regressed by O2 vectorization, refer to PR102697/PR102462/PR102706
> > > > +proc check_vect_slp_aligned_store_usage { pattern macro } {
> > > > +    global tool
> > > > +
> > > > +    set result [check_compile slp_aligned_store_usage assembly {
> > > > +       char a[16] __attribute__ ((aligned (16)));
> > > > +       short b[4] __attribute__((aligned(8)));
> > > > +       int c[4] __attribute__((aligned(16)));
> > > > +       #ifdef TEST_V8QI
> > > > +       void
> > > > +       foo ()
> > > > +       {
> > > > +           a[0] = 0;
> > > > +           a[1] = 1;
> > > > +           a[2] = 2;
> > > > +           a[3] = 3;
> > > > +           a[4] = 4;
> > > > +           a[5] = 5;
> > > > +           a[6] = 6;
> > > > +           a[7] = 7;
> > > > +       }
> > > > +       #elif TEST_V16QI
> > > > +       void
> > > > +       foo1 ()
> > > > +       {
> > > > +           a[0] = 0;
> > > > +           a[1] = 1;
> > > > +           a[2] = 2;
> > > > +           a[3] = 3;
> > > > +           a[4] = 4;
> > > > +           a[5] = 5;
> > > > +           a[6] = 6;
> > > > +           a[7] = 7;
> > > > +           a[8] = 8;
> > > > +           a[9] = 9;
> > > > +           a[10] = 10;
> > > > +           a[11] = 11;
> > > > +           a[12] = 12;
> > > > +           a[13] = 13;
> > > > +           a[14] = 14;
> > > > +           a[15] = 15;
> > > > +       }
> > > > +       #elif TEST_V4QI
> > > > +       void
> > > > +       foo2 ()
> > > > +       {
> > > > +           a[0] = 0;
> > > > +           a[1] = 1;
> > > > +           a[2] = 2;
> > > > +           a[3] = 3;
> > > > +       }
> > > > +       #elif TEST_V2QI
> > > > +       void
> > > > +       foo3 ()
> > > > +       {
> > > > +           a[0] = 0;
> > > > +           a[1] = 1;
> > > > +       }
> > > > +       #elif TEST_V2HI
> > > > +       void
> > > > +       foo4 ()
> > > > +       {
> > > > +           b[0] = 0;
> > > > +           b[1] = 1;
> > > > +       }
> > > > +       #elif TEST_V4HI
> > > > +       void
> > > > +       foo5 ()
> > > > +       {
> > > > +           b[0] = 0;
> > > > +           b[1] = 1;
> > > > +           b[2] = 2;
> > > > +           b[3] = 3;
> > > > +       }
> > > > +       #elif TEST_V2SI
> > > > +       void
> > > > +       foo6 ()
> > > > +       {
> > > > +           c[0] = 0;
> > > > +           c[1] = 1;
> > > > +       }
> > > > +       #elif TEST_V4SI
> > > > +       void
> > > > +       foo7 ()
> > > > +       {
> > > > +           c[0] = 0;
> > > > +           c[1] = 1;
> > > > +           c[2] = 2;
> > > > +           c[3] = 3;
> > > > +       }
> > > > +       #endif
> > > > +    } "-O2 -fopt-info-all -D$macro" ]
> > > > +
> > > > +      # Get compiler emitted messages and delete generated file.
> > > > +      set lines [lindex $result 0]
> > > > +      set output [lindex $result 1]
> > > > +      remote_file build delete $output
> > > > +
> > > > +      # Check pattern exits in lines, set it to zero if not found.
> > > > +      if { [regexp $pattern $lines] } then {
> > > > +        return 1
> > > > +      }
> > > > +
> > > > +    return 0
> > > > +}
> > > > +
> > > > +# Return the true if target support vectorization of 2-byte char stores
> > > > +# with 2-byte aligned address at plain O2.
> > > > +proc check_effective_target_vect_slp_v2qi_store { } {
> > > > +    set pattern {add new stmt: MEM <vector\(2\) char>}
> > > > +    set macro "TEST_V2QI"
> > > > +    return [check_cached_effective_target vect_slp_v2qi_store {
> > > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro] }]
> > > > +
> > > > +}
> > > > +
> > > > +# Return the true if target support vectorization of 4-byte char stores
> > > > +# with 4-byte aligned address at plain O2.
> > > > +proc check_effective_target_vect_slp_v4qi_store { } {
> > > > +    set pattern {add new stmt: MEM <vector\(4\) char>}
> > > > +    set macro "TEST_V4QI"
> > > > +    return [check_cached_effective_target vect_slp_v4qi_store {
> > > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > > > +}
> > > > +
> > > > +# Return the true if target support vectorization of 8-byte char stores
> > > > +# with 8-byte aligned address at plain O2.
> > > > +proc check_effective_target_vect_slp_v8qi_store { } {
> > > > +    set pattern {add new stmt: MEM <vector\(8\) char>}
> > > > +    set macro "TEST_V8QI"
> > > > +    return [check_cached_effective_target vect_slp_v8qi_store {
> > > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > > > +}
> > > > +
> > > > +# Return the true if target support vectorization of 16-byte char stores
> > > > +# with 16-byte aligned address at plain O2.
> > > > +proc check_effective_target_vect_slp_v16qi_store { } {
> > > > +    set pattern {add new stmt: MEM <vector\(16\) char>}
> > > > +    set macro "TEST_V16QI"
> > > > +    return [check_cached_effective_target vect_slp_v16qi_store {
> > > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > > > +}
> > > > +
> > > > +# Return the true if target support vectorization of 4-byte short stores
> > > > +# with 4-byte aligned address at plain O2.
> > > > +proc check_effective_target_vect_slp_v2hi_store { } {
> > > > +    set pattern {add new stmt: MEM <vector\(2\) short int>}
> > > > +    set macro "TEST_V2HI"
> > > > +    return [check_cached_effective_target vect_slp_v2hi_store {
> > > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > > > +}
> > > > +
> > > > +# Return the true if target support vectorization of 8-byte short stores
> > > > +# with 8-byte aligned address at plain O2.
> > > > +proc check_effective_target_vect_slp_v4hi_store { } {
> > > > +    set pattern {add new stmt: MEM <vector\(4\) short int>}
> > > > +    set macro "TEST_V4HI"
> > > > +    return [check_cached_effective_target vect_slp_v4hi_store {
> > > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > > > +}
> > > > +
> > > > +# Return the true if target support vectorization of 8-byte int stores
> > > > +# with 8-byte aligned address at plain O2.
> > > > +proc check_effective_target_vect_slp_v2si_store { } {
> > > > +    set pattern {add new stmt: MEM <vector\(2\) int>}
> > > > +    set macro "TEST_V2SI"
> > > > +    return [check_cached_effective_target vect_slp_v2si_store {
> > > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > > > +}
> > > > +
> > > > +# Return the true if target support vectorization of 16-byte int stores
> > > > +# with 16-byte aligned address at plain O2.
> > > > +proc check_effective_target_vect_slp_v4si_store { } {
> > > > +    set pattern {add new stmt: MEM <vector\(4\) int>}
> > > > +    set macro "TEST_V4SI"
> > > > +    return [check_cached_effective_target vect_slp_v4si_store {
> > > > +       expr [check_vect_slp_aligned_store_usage $pattern $macro ] }]
> > > > +}
> > > > +
> > > >  # Return 1 if we can align stack data to the preferred vector alignment.
> > > >
> > > >  proc check_effective_target_vect_align_stack_vars { } {
> > > > --
> > > > 2.18.1
> > > >
> > > >
> >
> >
> >
> > --
> > BR,
> > Hongtao
>
>
>
> --
> BR,
> Hongtao



-- 
BR,
Hongtao

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2021-10-21  2:07 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-11  2:47 [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658] Kewen.Lin
2021-10-11 15:30 ` Segher Boessenkool
2021-10-11 16:23   ` Martin Sebor
2021-10-11 17:43     ` Segher Boessenkool
2021-10-11 20:07       ` Martin Sebor
2021-10-12  2:31         ` Hongtao Liu
2021-10-12 15:49           ` Martin Sebor
2021-10-12 16:18             ` Segher Boessenkool
2021-10-12 17:15               ` Martin Sebor
2021-10-12 17:45                 ` Jeff Law
2021-10-12 18:01                 ` Segher Boessenkool
2021-10-13  3:34             ` Hongtao Liu
2021-10-13  6:29               ` Hongtao Liu
2021-10-13  7:43                 ` Kewen.Lin
2021-10-13 14:36                   ` Martin Sebor
2021-10-14  7:11                   ` [PATCH] Adjust testcase for O2 vectorization liuhongt
2021-10-14  7:52                     ` Bernhard Reutner-Fischer
2021-10-14 10:56                     ` Kewen.Lin
2021-10-15  7:11                       ` Kewen.Lin
2021-10-18  4:47                         ` Hongtao Liu
2021-10-15 15:37                     ` Martin Sebor
2021-10-18  4:38                       ` Hongtao Liu
2021-10-18 15:11                         ` Martin Sebor
2021-10-19  9:03                           ` liuhongt
2021-10-20 11:34                             ` Christophe Lyon
2021-10-21  1:20                               ` Hongtao Liu
2021-10-21  2:06                                 ` Hongtao Liu
2021-10-21  2:07                                   ` Hongtao Liu
2021-10-12 18:11         ` [PATCH] rs6000/test: Adjust some cases due to O2 vect [PR102658] Segher Boessenkool

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).