From bb0f5ca786de6649e1350b281d289ed4ad871b9e Mon Sep 17 00:00:00 2001 From: Alan Lawrence Date: Fri, 8 Jan 2016 18:02:35 +0000 Subject: [PATCH] [PATCH] Fix PR68707 gcc/: * tree-vect-slp.c (vect_analyze_slp_instance): Cancel permuted SLP instances that can be handled via vect_load_lanes. gcc/testsuite/: * lib/target-supports.exp (check_effective_target_vect_load_lanes): New. * gcc.dg/vect/slp-perm-1.c: Look for vect_load_lanes instead of SLP on platforms supporting it. * gcc.dg/vect/slp-perm-2.c: Likewise. * gcc.dg/vect/slp-perm-3.c: Likewise. * gcc.dg/vect/slp-perm-5.c: Likewise. * gcc.dg/vect/slp-perm-7.c: Likewise. * gcc.dg/vect/slp-perm-8.c: Likewise. * gcc.dg/vect/slp-perm-6.c: Look for vect_load_lanes in addition to SLP on platforms supporting it. Co-Authored-By: Richard Biener From-SVN: r232174 --- gcc/ChangeLog | 7 ++++++ gcc/testsuite/ChangeLog | 14 ++++++++++++ gcc/testsuite/gcc.dg/vect/slp-perm-1.c | 6 +++++- gcc/testsuite/gcc.dg/vect/slp-perm-2.c | 7 ++++-- gcc/testsuite/gcc.dg/vect/slp-perm-3.c | 7 ++++-- gcc/testsuite/gcc.dg/vect/slp-perm-5.c | 7 ++++-- gcc/testsuite/gcc.dg/vect/slp-perm-6.c | 7 ++++-- gcc/testsuite/gcc.dg/vect/slp-perm-7.c | 8 ++++--- gcc/testsuite/gcc.dg/vect/slp-perm-8.c | 7 ++++-- gcc/testsuite/lib/target-supports.exp | 19 ++++++++++++++++ gcc/tree-vect-slp.c | 30 ++++++++++++++++++++++++++ 11 files changed, 105 insertions(+), 14 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c3524fcde18c..2cb0b0196bcf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-01-08 Alan Lawrence + Richard Biener + + PR tree-optimization/68707 + * tree-vect-slp.c (vect_analyze_slp_instance): Cancel permuted SLP + instances that can be handled via vect_load_lanes. + 2016-01-08 Uros Bizjak * symtab.c (symtab_node::equal_address_to): Return -1 instead of 2 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f455fa22096c..235eab744931 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,17 @@ +2016-01-08 Alan Lawrence + + PR tree-optimization/68707 + * lib/target-supports.exp (check_effective_target_vect_load_lanes): New. + * gcc.dg/vect/slp-perm-1.c: Look for vect_load_lanes instead of SLP + on platforms supporting it. + * gcc.dg/vect/slp-perm-2.c: Likewise. + * gcc.dg/vect/slp-perm-3.c: Likewise. + * gcc.dg/vect/slp-perm-5.c: Likewise. + * gcc.dg/vect/slp-perm-7.c: Likewise. + * gcc.dg/vect/slp-perm-8.c: Likewise. + * gcc.dg/vect/slp-perm-6.c: Look for vect_load_lanes in addition to SLP + on platforms supporting it. + 2016-01-08 Jakub Jelinek PR tree-optimization/69162 diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c index 2b6c13498860..6d0d66f9c210 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c @@ -58,5 +58,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_perm } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm && {! vect_load_lanes } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */ +/* { dg-final { scan-tree-dump "note: Built SLP cancelled: can use load/store-lanes" { target { vect_perm && 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-2.c b/gcc/testsuite/gcc.dg/vect/slp-perm-2.c index da50e16d5bdf..34b413d0dd65 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-perm-2.c +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-2.c @@ -54,5 +54,8 @@ 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_perm } } } */ - +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm && {! vect_load_lanes } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */ +/* { dg-final { scan-tree-dump "note: Built SLP cancelled: can use load/store-lanes" { target { vect_perm && 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-3.c b/gcc/testsuite/gcc.dg/vect/slp-perm-3.c index 1d33f9b4737a..ec13e0f54f50 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-perm-3.c +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-3.c @@ -67,6 +67,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_perm } } } */ - +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm && {! vect_load_lanes } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */ +/* { dg-final { scan-tree-dump "note: Built SLP cancelled: can use load/store-lanes" { target { vect_perm && 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 9ed4d724919a..f44f44ffd9fc 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-perm-5.c +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-5.c @@ -73,6 +73,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_perm } } } */ - +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm && {! vect_load_lanes } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */ +/* { dg-final { scan-tree-dump "note: Built SLP cancelled: can use load/store-lanes" { target { vect_perm && 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 392d36f3ed9c..551734ac4c0c 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-perm-6.c +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-6.c @@ -72,5 +72,8 @@ 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_perm } } } */ - +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm && {! vect_load_lanes } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_load_lanes } } } */ +/* { dg-final { scan-tree-dump "note: Built SLP cancelled: can use load/store-lanes" { target { vect_perm && 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 435233439fa8..8b66142a9ef3 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-perm-7.c +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-7.c @@ -71,6 +71,8 @@ int main (int argc, const char* argv[]) } /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_perm } } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_perm } } } */ - - +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm && {! vect_load_lanes } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */ +/* { dg-final { scan-tree-dump "note: Built SLP cancelled: can use load/store-lanes" { target { vect_perm && 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 3bdd15061db2..b1e9a10e35ec 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-perm-8.c +++ b/gcc/testsuite/gcc.dg/vect/slp-perm-8.c @@ -54,5 +54,8 @@ int main (int argc, const char* argv[]) /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target { vect_perm_byte && vect_char_mult } } } } */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_perm_byte && {! vect_char_mult } } } } } */ -/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_perm_byte } } } */ - +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm_byte && {! vect_load_lanes } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */ +/* { dg-final { scan-tree-dump "note: Built SLP cancelled: can use load/store-lanes" { target { vect_perm_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/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 4030b35fe72e..31a4f60e4edd 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -4876,6 +4876,25 @@ proc check_effective_target_vect_element_align { } { return $et_vect_element_align } +# Return 1 if the target supports vector LOAD_LANES operations, 0 otherwise. + +proc check_effective_target_vect_load_lanes { } { + global et_vect_load_lanes + + if [info exists et_vect_load_lanes] { + verbose "check_effective_target_vect_load_lanes: using cached result" 2 + } else { + set et_vect_load_lanes 0 + if { ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]) + || [istarget aarch64*-*-*] } { + set et_vect_load_lanes 1 + } + } + + verbose "check_effective_target_vect_load_lanes: returning $et_vect_load_lanes" 2 + return $et_vect_load_lanes +} + # Return 1 if the target supports vector conditional operations, 0 otherwise. proc check_effective_target_vect_condition { } { diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index b029f6179754..0aac2e2f6cfd 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -1820,6 +1820,36 @@ vect_analyze_slp_instance (vec_info *vinfo, } } + /* If the loads and stores can be handled with load/store-lane + instructions do not generate this SLP instance. */ + if (is_a (vinfo) + && loads_permuted + && dr && vect_store_lanes_supported (vectype, group_size)) + { + slp_tree load_node; + FOR_EACH_VEC_ELT (loads, i, load_node) + { + gimple *first_stmt = GROUP_FIRST_ELEMENT + (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (load_node)[0])); + stmt_vec_info stmt_vinfo = vinfo_for_stmt (first_stmt); + /* Use SLP for strided accesses (or if we can't load-lanes). */ + if (STMT_VINFO_STRIDED_P (stmt_vinfo) + || ! vect_load_lanes_supported + (STMT_VINFO_VECTYPE (stmt_vinfo), + GROUP_SIZE (stmt_vinfo))) + break; + } + if (i == loads.length ()) + { + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Built SLP cancelled: can use " + "load/store-lanes\n"); + vect_free_slp_instance (new_instance); + return false; + } + } + vinfo->slp_instances.safe_push (new_instance); if (dump_enabled_p ())