diff mbox series

testsuite: Update some vect cases for partial vectors

Message ID b2aa89c9-8d2e-ba5f-f52f-372146fbe863@linux.ibm.com
State New
Headers show
Series testsuite: Update some vect cases for partial vectors | expand

Commit Message

Kewen.Lin Aug. 5, 2020, 9:22 a.m. UTC
Hi,

This patch is to adjust some existing vectorization test cases
to stay well with the newly introduced partial vector usages.

Bootstrapped/regtested on aarch64-linux-gnu and powerpc64le-linux-gnu
P9 (with explicit param vect-partial-vector-usage=1 and enablement on
check_effective_target_vect_partial_vectors_usage_1 check).

Is it ok for trunk?

BR,
Kewen
-----

gcc/testsuite/ChangeLog:

	* gcc.dg/vect/bb-slp-pr69907.c: Adjust for partial vector usages.
	* gcc.dg/vect/slp-3.c: Likewise.
	* gcc.dg/vect/slp-multitypes-11.c: Likewise.
	* gcc.dg/vect/slp-perm-1.c: Likewise.
	* gcc.dg/vect/slp-perm-5.c: Likewise.
	* gcc.dg/vect/slp-perm-6.c: Likewise.
	* gcc.dg/vect/slp-perm-7.c: Likewise.
	* gcc.dg/vect/slp-perm-8.c: Likewise.
	* gcc.dg/vect/slp-perm-9.c: Likewise.
	* gcc.dg/vect/vect-version-2.c: Likewise.
	* lib/target-supports.exp
	(check_effective_target_vect_partial_vectors): New function.
	(check_effective_target_vect_partial_vectors_usage_1): Likewise.
	(check_effective_target_vect_partial_vectors_usage_2): Likewise.

Comments

Richard Sandiford Aug. 6, 2020, 5:52 a.m. UTC | #1
"Kewen.Lin" <linkw@linux.ibm.com> writes:
> diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c
> index 5200ed1cd94..da6fb12eb0d 100644
> --- a/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c
> +++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c
> @@ -48,6 +48,9 @@ int main (void)
>    return 0;
>  }
>  
> -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target vect_unpack } } } */
> -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect"  { target vect_unpack xfail { vect_variable_length && vect_load_lanes } } } } */
> +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target { vect_unpack && {! vect_partial_vectors_usage_1 } } } } } */
> +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target { vect_unpack && { vect_partial_vectors_usage_1 } } } } } */

I don't understand this bit: don't these two lines reduce back to the
original vect_unpack one?

> +/* The epilogues are vectorized using partial vectors.  */
> +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect"  { target { vect_unpack && {! vect_partial_vectors_usage_1 } } xfail { vect_variable_length && vect_load_lanes } } } } */
> +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect"  { target { vect_unpack && { vect_partial_vectors_usage_1 } } xfail { vect_variable_length && vect_load_lanes } } } } */
>    
> diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
> index ca7803ec1a9..af6fe08856f 100644
> --- a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
> +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
> @@ -80,8 +80,10 @@ int main (int argc, const char* argv[])
>  }
>  
>  /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target vect_perm } } } */
> -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && {! vect_load_lanes } } } } } */
> +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && {! vect_partial_vectors_usage_1 } } } } } } */
>  /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */
> +/* The epilogues are vectorized using partial vectors.  */
> +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && { vect_partial_vectors_usage_1 } } } } } } */

Very minor, but I think it'd be better to put this immediately after the
line you changed above.  Same for the other slp-perm-* changes.

> diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
> index 57eed3012b9..b571e84d20e 100644
> --- a/gcc/testsuite/lib/target-supports.exp
> +++ b/gcc/testsuite/lib/target-supports.exp
> @@ -7055,6 +7055,27 @@ proc check_effective_target_vect_check_ptrs { } {
>      return [check_effective_target_aarch64_sve2]
>  }
>  
> +# Return true if loops using partial vectors are supported.
> +
> +proc check_effective_target_vect_partial_vectors { } {
> +    return [expr { [check_effective_target_vect_partial_vectors_usage_1]
> +		   || [check_effective_target_vect_partial_vectors_usage_2] }]
> +}
> +
> +# Return true if loops using partial vectors are supported and the default
> +# value of --param=vect-partial-vector-usage is 1.
> +
> +proc check_effective_target_vect_partial_vectors_usage_1 { } {
> +    return 0
> +}
> +
> +# Return true if loops using partial vectors are supported and the default
> +# value of --param=vect-partial-vector-usage is 2.
> +
> +proc check_effective_target_vect_partial_vectors_usage_2 { } {
> +    return [expr { [check_effective_target_vect_fully_masked] }]
> +}
> +

Could we auto-detect this?  What we really care about isn't the default,
but what's currently being tested.

E.g. maybe use check_compile to run gcc with “-Q --help=params” and an
arbitrary output type (probably assembly).  Then use “regexp” on the
lines to parse the --param=vect-partial-vector-usage value.  At that
point it would be worth caching the result.

The new target-supports keywords need to be documented in sourcebuild.texi.

Thanks,
Richard
Kewen.Lin Aug. 6, 2020, 7:37 a.m. UTC | #2
Hi Richard,

Thanks for the review!

on 2020/8/6 下午1:52, Richard Sandiford wrote:
> "Kewen.Lin" <linkw@linux.ibm.com> writes:
>> diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c
>> index 5200ed1cd94..da6fb12eb0d 100644
>> --- a/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c
>> +++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c
>> @@ -48,6 +48,9 @@ int main (void)
>>    return 0;
>>  }
>>  
>> -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target vect_unpack } } } */
>> -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect"  { target vect_unpack xfail { vect_variable_length && vect_load_lanes } } } } */
>> +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target { vect_unpack && {! vect_partial_vectors_usage_1 } } } } } */
>> +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target { vect_unpack && { vect_partial_vectors_usage_1 } } } } } */
> 
> I don't understand this bit: don't these two lines reduce back to the
> original vect_unpack one?

Yes, we don't need them.  Sorry that I duplicated it for the different conditions like the one after it,
but forgot to change it back when found it's useless.  Thanks for catching!

> 
>> +/* The epilogues are vectorized using partial vectors.  */
>> +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect"  { target { vect_unpack && {! vect_partial_vectors_usage_1 } } xfail { vect_variable_length && vect_load_lanes } } } } */
>> +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect"  { target { vect_unpack && { vect_partial_vectors_usage_1 } } xfail { vect_variable_length && vect_load_lanes } } } } */
>>    
>> diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
>> index ca7803ec1a9..af6fe08856f 100644
>> --- a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
>> +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
>> @@ -80,8 +80,10 @@ int main (int argc, const char* argv[])
>>  }
>>  
>>  /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target vect_perm } } } */
>> -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && {! vect_load_lanes } } } } } */
>> +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && {! vect_partial_vectors_usage_1 } } } } } } */
>>  /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */
>> +/* The epilogues are vectorized using partial vectors.  */
>> +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && { vect_partial_vectors_usage_1 } } } } } } */
> 
> Very minor, but I think it'd be better to put this immediately after the
> line you changed above.  Same for the other slp-perm-* changes.
> 

OK, will fix.

>> diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
>> index 57eed3012b9..b571e84d20e 100644
>> --- a/gcc/testsuite/lib/target-supports.exp
>> +++ b/gcc/testsuite/lib/target-supports.exp
>> @@ -7055,6 +7055,27 @@ proc check_effective_target_vect_check_ptrs { } {
>>      return [check_effective_target_aarch64_sve2]
>>  }
>>  
>> +# Return true if loops using partial vectors are supported.
>> +
>> +proc check_effective_target_vect_partial_vectors { } {
>> +    return [expr { [check_effective_target_vect_partial_vectors_usage_1]
>> +		   || [check_effective_target_vect_partial_vectors_usage_2] }]
>> +}
>> +
>> +# Return true if loops using partial vectors are supported and the default
>> +# value of --param=vect-partial-vector-usage is 1.
>> +
>> +proc check_effective_target_vect_partial_vectors_usage_1 { } {
>> +    return 0
>> +}
>> +
>> +# Return true if loops using partial vectors are supported and the default
>> +# value of --param=vect-partial-vector-usage is 2.
>> +
>> +proc check_effective_target_vect_partial_vectors_usage_2 { } {
>> +    return [expr { [check_effective_target_vect_fully_masked] }]
>> +}
>> +
> 
> Could we auto-detect this?  What we really care about isn't the default,
> but what's currently being tested.

Yeah, the comments were confusing, its intent is to check which targets
support partial vectors and which usage to be used.

How about to update them like:

"Return true if loops using partial vectors are supported and usage kind is
1/2".

> 
> E.g. maybe use check_compile to run gcc with “-Q --help=params” and an
> arbitrary output type (probably assembly).  Then use “regexp” on the
> lines to parse the --param=vect-partial-vector-usage value.  At that
> point it would be worth caching the result.

Now the default value of this parameter is 2, even for those targets which
don't have the supports with partial vectors.  Since we will get the value
2 on those unsupported targets, it looks like we have to set it manually?

> 
> The new target-supports keywords need to be documented in sourcebuild.texi.
> 

Will add it, thanks for the information!


BR,
Kewen
Richard Sandiford Aug. 6, 2020, 8:46 a.m. UTC | #3
"Kewen.Lin" <linkw@linux.ibm.com> writes:
>>> +# Return true if loops using partial vectors are supported.
>>> +
>>> +proc check_effective_target_vect_partial_vectors { } {
>>> +    return [expr { [check_effective_target_vect_partial_vectors_usage_1]
>>> +		   || [check_effective_target_vect_partial_vectors_usage_2] }]
>>> +}
>>> +
>>> +# Return true if loops using partial vectors are supported and the default
>>> +# value of --param=vect-partial-vector-usage is 1.
>>> +
>>> +proc check_effective_target_vect_partial_vectors_usage_1 { } {
>>> +    return 0
>>> +}
>>> +
>>> +# Return true if loops using partial vectors are supported and the default
>>> +# value of --param=vect-partial-vector-usage is 2.
>>> +
>>> +proc check_effective_target_vect_partial_vectors_usage_2 { } {
>>> +    return [expr { [check_effective_target_vect_fully_masked] }]
>>> +}
>>> +
>> 
>> Could we auto-detect this?  What we really care about isn't the default,
>> but what's currently being tested.
>
> Yeah, the comments were confusing, its intent is to check which targets
> support partial vectors and which usage to be used.
>
> How about to update them like:
>
> "Return true if loops using partial vectors are supported and usage kind is
> 1/2".

I wasn't really commenting on the comment so much as the intent.
It should be possible to run the testsuite with:

  --target_board unix/--param=vect-partial-vector-usage=1

and get the right results.

>> E.g. maybe use check_compile to run gcc with “-Q --help=params” and an
>> arbitrary output type (probably assembly).  Then use “regexp” on the
>> lines to parse the --param=vect-partial-vector-usage value.  At that
>> point it would be worth caching the result.
>
> Now the default value of this parameter is 2, even for those targets which
> don't have the supports with partial vectors.  Since we will get the value
> 2 on those unsupported targets, it looks like we have to set it manually?

I think that just means we want:

vect_len_load_store
  the len_load_store equivalent of vect_fully_masked, i.e. whether
  the target supports len load/store (regardless of whether the
  --param enables it)

vect_partial_vectors
  (vect_fully_masked || vect_len_load_store) && param != 0

vect_partial_vectors_usage_1
  (vect_fully_masked || vect_len_load_store) && param == 1

vect_partial_vectors_usage_2
  (vect_fully_masked || vect_len_load_store) && param == 2

Thanks,
Richard
diff mbox series

Patch

diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr69907.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr69907.c
index fe52d18525a..b348526b62f 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr69907.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr69907.c
@@ -1,5 +1,7 @@ 
 /* { dg-do compile } */
-/* { dg-additional-options "-O3" } */
+/* Disable for vectorization using partial vectors since it would have only
+   one iteration left, consequently BB vectorization won't happen.  */
+/* { dg-additional-options "-O3 --param=vect-partial-vector-usage=0" } */
 /* { dg-require-effective-target vect_unpack } */
 
 #include "tree-vect.h"
diff --git a/gcc/testsuite/gcc.dg/vect/slp-3.c b/gcc/testsuite/gcc.dg/vect/slp-3.c
index 5e40499ff96..46ab584419a 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-3.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-3.c
@@ -141,8 +141,8 @@  int main (void)
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { target { ! vect_fully_masked } } } } */
-/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" { target vect_fully_masked } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { target { ! vect_fully_masked } } } }*/
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target vect_fully_masked } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { target { ! vect_partial_vectors } } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" { target vect_partial_vectors } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { target { ! vect_partial_vectors } } } }*/
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target vect_partial_vectors } } } */
   
diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c
index 5200ed1cd94..da6fb12eb0d 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c
@@ -48,6 +48,9 @@  int main (void)
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target vect_unpack } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect"  { target vect_unpack xfail { vect_variable_length && vect_load_lanes } } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target { vect_unpack && {! vect_partial_vectors_usage_1 } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target { vect_unpack && { vect_partial_vectors_usage_1 } } } } } */
+/* The epilogues are vectorized using partial vectors.  */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect"  { target { vect_unpack && {! vect_partial_vectors_usage_1 } } xfail { vect_variable_length && vect_load_lanes } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect"  { target { vect_unpack && { vect_partial_vectors_usage_1 } } xfail { vect_variable_length && vect_load_lanes } } } } */
   
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
index ca7803ec1a9..af6fe08856f 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
@@ -80,8 +80,10 @@  int main (int argc, const char* argv[])
 }
 
 /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target vect_perm } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && {! vect_load_lanes } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && {! vect_partial_vectors_usage_1 } } } } } } */
 /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */
+/* The epilogues are vectorized using partial vectors.  */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && { vect_partial_vectors_usage_1 } } } } } } */
 /* { dg-final { scan-tree-dump "Built SLP cancelled: can use load/store-lanes" "vect" { target { vect_perm3_int && vect_load_lanes } } } } */
 /* { dg-final { scan-tree-dump "LOAD_LANES" "vect" { target vect_load_lanes } } } */
 /* { dg-final { scan-tree-dump "STORE_LANES" "vect" { target vect_load_lanes } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-5.c b/gcc/testsuite/gcc.dg/vect/slp-perm-5.c
index b86a3dc8756..a1affbc9419 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-5.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-5.c
@@ -104,8 +104,10 @@  int main (int argc, const char* argv[])
 }
 
 /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target vect_perm } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { ! vect_load_lanes } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && {! vect_partial_vectors_usage_1 } } } } } } */
 /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */
+/* The epilogues are vectorized using partial vectors.  */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && { vect_partial_vectors_usage_1 } } } } } } */
 /* { dg-final { scan-tree-dump "Built SLP cancelled: can use load/store-lanes" "vect" { target { vect_perm3_int && vect_load_lanes } } } } */
 /* { dg-final { scan-tree-dump "LOAD_LANES" "vect" { target vect_load_lanes } } } */
 /* { dg-final { scan-tree-dump "STORE_LANES" "vect" { target vect_load_lanes } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-6.c b/gcc/testsuite/gcc.dg/vect/slp-perm-6.c
index 97a0ebffe01..e2f1451bdeb 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-6.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-6.c
@@ -103,8 +103,10 @@  int main (int argc, const char* argv[])
 }
 
 /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target vect_perm } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { ! vect_load_lanes } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && {! vect_partial_vectors_usage_1 } } } } } } */
 /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_load_lanes } } } */
+/* The epilogues are vectorized using partial vectors.  */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && { vect_partial_vectors_usage_1 } } } } } } */
 /* { dg-final { scan-tree-dump "Built SLP cancelled: can use load/store-lanes" "vect" { target { vect_perm3_int && vect_load_lanes } } } } */
 /* { dg-final { scan-tree-dump "LOAD_LANES" "vect" { target vect_load_lanes } } } */
 /* { dg-final { scan-tree-dump "STORE_LANES" "vect" { target vect_load_lanes } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-7.c b/gcc/testsuite/gcc.dg/vect/slp-perm-7.c
index 346411fd504..a926fe9f052 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-7.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-7.c
@@ -96,8 +96,10 @@  int main (int argc, const char* argv[])
 }
 
 /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"  { target vect_perm } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && { ! vect_load_lanes } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && {! vect_partial_vectors_usage_1 } } } } } } */
 /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */
+/* The epilogues are vectorized using partial vectors.  */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && { vect_partial_vectors_usage_1 } } } } } } */
 /* { dg-final { scan-tree-dump "Built SLP cancelled: can use load/store-lanes" "vect" { target { vect_perm3_int && vect_load_lanes } } } } */
 /* { dg-final { scan-tree-dump "LOAD_LANES" "vect" { target vect_load_lanes } } } */
 /* { dg-final { scan-tree-dump "STORE_LANES" "vect" { target vect_load_lanes } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-8.c b/gcc/testsuite/gcc.dg/vect/slp-perm-8.c
index 17aa111437a..40e562bc71a 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-8.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-8.c
@@ -60,8 +60,10 @@  int main (int argc, const char* argv[])
 }
 
 /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_perm_byte } } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_byte && { ! vect_load_lanes } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_byte && { { ! vect_load_lanes } && {! vect_partial_vectors_usage_1 } } } } } } */
 /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */
+/* The epilogues are vectorized using partial vectors.  */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_byte && { { ! vect_load_lanes } && { vect_partial_vectors_usage_1 } } } } } } */
 /* { dg-final { scan-tree-dump "Built SLP cancelled: can use load/store-lanes" "vect" { target { vect_perm3_byte && vect_load_lanes } } } } */
 /* { dg-final { scan-tree-dump "LOAD_LANES" "vect" { target vect_load_lanes } } } */
 /* { dg-final { scan-tree-dump "STORE_LANES" "vect" { target vect_load_lanes } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-9.c b/gcc/testsuite/gcc.dg/vect/slp-perm-9.c
index c54420abd9d..e1e350bf7b7 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-9.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-9.c
@@ -61,7 +61,9 @@  int main (int argc, const char* argv[])
 /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_perm_short || vect_load_lanes } } } } */
 /* We don't try permutes with a group size of 3 for variable-length
    vectors.  */
-/* { dg-final { scan-tree-dump-times "permutation requires at least three vectors" 1 "vect" { target { vect_perm_short && { ! vect_perm3_short } } xfail vect_variable_length } } } */
+/* { dg-final { scan-tree-dump-times "permutation requires at least three vectors" 1 "vect" { target { vect_perm_short && { { ! vect_perm3_short } && { ! vect_partial_vectors_usage_1 } } } xfail vect_variable_length } } } */
+/* Try to vectorize the epilogue using partial vectors.  */
+/* { dg-final { scan-tree-dump-times "permutation requires at least three vectors" 2 "vect" { target { vect_perm_short && { { ! vect_perm3_short } && { vect_partial_vectors_usage_1 } } } xfail vect_variable_length } } } */
 /* { dg-final { scan-tree-dump-not "permutation requires at least three vectors" "vect" { target vect_perm3_short } } } */
 /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target { { ! vect_perm3_short } || vect_load_lanes } } } } */
 /* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_short && { ! vect_load_lanes } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-version-2.c b/gcc/testsuite/gcc.dg/vect/vect-version-2.c
index 0ea39e31801..7d3fb722f47 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-version-2.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-version-2.c
@@ -17,4 +17,8 @@  void foo (double *x, double *y, int m, int n, int o, int p)
 	  }
 }
 
-/* { dg-final { scan-tree-dump "reusing loop version created by if conversion" "vect" } } */
+/* Vectorization using partial vectors has zero versioning_threshold with
+   either usage 1 or usage 2, the cond_expr replies on the computation in
+   outer loop, so it doesn't need to reuse the loop version created by if
+   conversion.  */
+/* { dg-final { scan-tree-dump "reusing loop version created by if conversion" "vect" {target {! vect_partial_vectors } } } } */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 57eed3012b9..b571e84d20e 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -7055,6 +7055,27 @@  proc check_effective_target_vect_check_ptrs { } {
     return [check_effective_target_aarch64_sve2]
 }
 
+# Return true if loops using partial vectors are supported.
+
+proc check_effective_target_vect_partial_vectors { } {
+    return [expr { [check_effective_target_vect_partial_vectors_usage_1]
+		   || [check_effective_target_vect_partial_vectors_usage_2] }]
+}
+
+# Return true if loops using partial vectors are supported and the default
+# value of --param=vect-partial-vector-usage is 1.
+
+proc check_effective_target_vect_partial_vectors_usage_1 { } {
+    return 0
+}
+
+# Return true if loops using partial vectors are supported and the default
+# value of --param=vect-partial-vector-usage is 2.
+
+proc check_effective_target_vect_partial_vectors_usage_2 { } {
+    return [expr { [check_effective_target_vect_fully_masked] }]
+}
+
 # Return true if fully-masked loops are supported.
 
 proc check_effective_target_vect_fully_masked { } {