Hi Richard,

>> 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 for the clarification!

Sorry for the late update, this new version depends on the --help= patch,
I held it for a while.

Bootstrapped/regtested on powerpc64le-linux-gnu P9, with/without any
explicit usage setting, it also works well with --target_board 
unix/--param=vect-partial-vector-usage=1.

By the way, for the testing on usage 1, it needs the function 
check_effective_target_vect_len_load_store to return true for Power9,
this part will be sent for review separately.

Is it ok for trunk?

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

        * doc/sourcebuild.texi (vect_len_load_store,
        vect_partial_vectors_usage_1, vect_partial_vectors_usage_2,
        vect_partial_vectors): Document.

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_vect_partial_vector_usage): New
        function.
        (check_effective_target_vect_len_load_store): Likewise.
        (check_effective_target_vect_partial_vectors_usage_1): Likewise.
        (check_effective_target_vect_partial_vectors_usage_2): Likewise.
        (check_effective_target_vect_partial_vectors): Likewise.
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 9f37ac26241..2290af5812d 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -1689,6 +1689,19 @@ Target supports AND, IOR and XOR reduction on vectors.
 
 @item vect_fold_extract_last
 Target supports the @code{fold_extract_last} optab.
+
+@item vect_len_load_store
+Target supports loops using length-based partial vectors.
+
+@item vect_partial_vectors_usage_1
+Target supports loops using partial vectors but only for those loops whose need
+to iterate can be removed.
+
+@item vect_partial_vectors_usage_2
+Target supports loops using partial vectors and for all loops.
+
+@item vect_partial_vectors
+Target supports loops using partial vectors.
 @end table
 
 @subsubsection Thread Local Storage attributes
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..d6b0604db78 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c
@@ -49,5 +49,7 @@ int main (void)
 }
 
 /* { 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 } } } } */
+/* 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..f1065d5598c 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
@@ -80,7 +80,9 @@ 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 } } } } } } */
+/* 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-times "vectorizing stmts using SLP" 0 "vect" { 
target vect_load_lanes } } } */
 /* { 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 } 
} } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-5.c 
b/gcc/testsuite/gcc.dg/vect/slp-perm-5.c
index b86a3dc8756..1fcf7146060 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-5.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-5.c
@@ -104,7 +104,9 @@ 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 } } } } } } */
+/* 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-times "vectorizing stmts using SLP" 0 "vect" { 
target vect_load_lanes } } } */
 /* { 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 } 
} } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-6.c 
b/gcc/testsuite/gcc.dg/vect/slp-perm-6.c
index 97a0ebffe01..d5d66249f81 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-6.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-6.c
@@ -103,7 +103,9 @@ 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 } } } } } } */
+/* 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-times "vectorizing stmts using SLP" 1 "vect" { 
target vect_load_lanes } } } */
 /* { 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 } 
} } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-7.c 
b/gcc/testsuite/gcc.dg/vect/slp-perm-7.c
index 346411fd504..0e414387344 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-7.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-7.c
@@ -96,7 +96,9 @@ 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 } } } } } } */
+/* 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-times "vectorizing stmts using SLP" 0 "vect" { 
target vect_load_lanes } } } */
 /* { 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 } 
} } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-8.c 
b/gcc/testsuite/gcc.dg/vect/slp-perm-8.c
index 17aa111437a..97ddc9ee6ce 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-8.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-8.c
@@ -60,7 +60,9 @@ 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 } } } } } } */
+/* 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-times "vectorizing stmts using SLP" 0 "vect" { 
target vect_load_lanes } } } */
 /* { 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 } 
} } */
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..5f84c80a37e 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -7062,6 +7062,66 @@ proc check_effective_target_vect_fully_masked { } {
                   || [istarget amdgcn*-*-*] }]
 }
 
+# Return true if loops using length-based partial vectors are supported.
+
+proc check_effective_target_vect_len_load_store { } {
+    return 0
+}
+
+# Return the value of parameter vect-partial-vector-usage specified for
+# target by checking the output of "-Q --help=params".  Return zero if
+# the desirable pattern isn't found.
+
+proc check_vect_partial_vector_usage { } {
+    global tool
+
+    return [check_cached_effective_target vect_partial_vector_usage {
+      set result [check_compile vect_partial_vector_usage assembly {
+         int i;
+      } "-Q --help=params" ]
+
+      # Get compiler emitted messages and delete generated file.
+      set lines [lindex $result 0]
+      set output [lindex $result 1]
+      remote_file build delete $output
+
+      set pattern {=vect-partial-vector-usage=<0,2>\s+([0-2])}
+      # Capture the usage value to val, set it to zero if not found.
+      if { ![regexp $pattern $lines whole val] } then {
+         set val 0
+      }
+
+      return $val
+    }]
+}
+
+# Return true if loops using partial vectors are supported but only for loops
+# whose need to iterate can be removed, that is, value of
+# param_vect_partial_vector_usage is set to 1.
+
+proc check_effective_target_vect_partial_vectors_usage_1 { } {
+    return [expr { ([check_effective_target_vect_fully_masked]
+                   || [check_effective_target_vect_len_load_store])
+                  && [check_vect_partial_vector_usage] == 1 }]
+}
+
+# Return true if loops using partial vectors are supported and for all loops,
+# that is, value of param_vect_partial_vector_usage is set to 2.
+
+proc check_effective_target_vect_partial_vectors_usage_2 { } {
+    return [expr { ([check_effective_target_vect_fully_masked]
+                   || [check_effective_target_vect_len_load_store])
+                  && [check_vect_partial_vector_usage] == 2 }]
+}
+
+# Return true if loops using partial vectors are supported.
+
+proc check_effective_target_vect_partial_vectors { } {
+    return [expr { ([check_effective_target_vect_fully_masked]
+                   || [check_effective_target_vect_len_load_store])
+                  && [check_vect_partial_vector_usage] != 0 }]
+}
+
 # Return 1 if the target doesn't prefer any alignment beyond element
 # alignment during vectorization.
 

Reply via email to