From 4e459157513bf006c7bbf523b2ffdfb6fbeee930 Mon Sep 17 00:00:00 2001 From: jakub Date: Tue, 4 Feb 2014 13:08:00 +0000 Subject: [PATCH] PR tree-optimization/60023 * tree-if-conv.c (predicate_mem_writes): Pass true instead of false to gsi_replace. * tree-vect-stmts.c (vect_finish_stmt_generation): If stmt has been in some EH region and vec_stmt could throw, add vec_stmt into the same EH region. * tree-data-ref.c (get_references_in_stmt): If IFN_MASK_LOAD has no lhs, ignore it. * internal-fn.c (expand_MASK_LOAD): Likewise. * g++.dg/vect/pr60023.cc: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@207464 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 +++++ gcc/internal-fn.c | 2 + gcc/testsuite/ChangeLog | 3 ++ gcc/testsuite/g++.dg/vect/pr60023.cc | 80 ++++++++++++++++++++++++++++++++++++ gcc/tree-data-ref.c | 2 + gcc/tree-if-conv.c | 2 +- gcc/tree-vect-stmts.c | 7 ++++ 7 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/vect/pr60023.cc diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6c6dfd6..17a6262 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2014-02-04 Jakub Jelinek + PR tree-optimization/60023 + * tree-if-conv.c (predicate_mem_writes): Pass true instead of + false to gsi_replace. + * tree-vect-stmts.c (vect_finish_stmt_generation): If stmt + has been in some EH region and vec_stmt could throw, add + vec_stmt into the same EH region. + * tree-data-ref.c (get_references_in_stmt): If IFN_MASK_LOAD + has no lhs, ignore it. + * internal-fn.c (expand_MASK_LOAD): Likewise. + PR ipa/60026 * tree-inline.c (copy_forbidden): Fail for __attribute__((optimize (0))) functions. diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index 43aaecb..3efd2b1 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -820,6 +820,8 @@ expand_MASK_LOAD (gimple stmt) maskt = gimple_call_arg (stmt, 2); lhs = gimple_call_lhs (stmt); + if (lhs == NULL_TREE) + return; type = TREE_TYPE (lhs); rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), gimple_call_arg (stmt, 1)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f23b6c4..4c49fc3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2014-02-04 Jakub Jelinek + PR tree-optimization/60023 + * g++.dg/vect/pr60023.cc: New test. + PR ipa/60026 * c-c++-common/torture/pr60026.c: New test. diff --git a/gcc/testsuite/g++.dg/vect/pr60023.cc b/gcc/testsuite/g++.dg/vect/pr60023.cc new file mode 100644 index 0000000..78f325e --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/pr60023.cc @@ -0,0 +1,80 @@ +// PR tree-optimization/60023 +// { dg-do compile } +// { dg-additional-options "-O3 -std=c++11 -fnon-call-exceptions" } +// { dg-additional-options "-mavx2" { target { i?86-*-* x86_64-*-* } } } + +struct A { A (); ~A (); }; + +void +f1 (int *p, int *q, int *r) noexcept (true) +{ + int i; + for (i = 0; i < 1024; i++) + if (r[i]) + p[i] = q[i] + 1; +} + +void +f2 (int *p, int *q, int *r) +{ + int i; + for (i = 0; i < 1024; i++) + if (r[i]) + p[i] = q[i] + 1; +} + +void +f3 (int *p, int *q) noexcept (true) +{ + int i; + for (i = 0; i < 1024; i++) + p[i] = q[i] + 1; +} + +void +f4 (int *p, int *q) +{ + int i; + for (i = 0; i < 1024; i++) + p[i] = q[i] + 1; +} + +void +f5 (int *p, int *q, int *r) noexcept (true) +{ + int i; + A a; + for (i = 0; i < 1024; i++) + if (r[i]) + p[i] = q[i] + 1; +} + +void +f6 (int *p, int *q, int *r) +{ + int i; + A a; + for (i = 0; i < 1024; i++) + if (r[i]) + p[i] = q[i] + 1; +} + +void +f7 (int *p, int *q) noexcept (true) +{ + int i; + A a; + for (i = 0; i < 1024; i++) + p[i] = q[i] + 1; +} + +void +f8 (int *p, int *q) +{ + int i; + A a; + for (i = 0; i < 1024; i++) + p[i] = q[i] + 1; +} + +// { dg-final { cleanup-tree-dump "vect" } } diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index 91601ef..01d0a7a 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -4401,6 +4401,8 @@ get_references_in_stmt (gimple stmt, vec *references) switch (gimple_call_internal_fn (stmt)) { case IFN_MASK_LOAD: + if (gimple_call_lhs (stmt) == NULL_TREE) + break; ref.is_read = true; case IFN_MASK_STORE: ref.ref = fold_build2 (MEM_REF, diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index d232776..0dc340f 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -1723,7 +1723,7 @@ predicate_mem_writes (loop_p loop) new_stmt = gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr, mask, rhs); - gsi_replace (&gsi, new_stmt, false); + gsi_replace (&gsi, new_stmt, true); } else if (gimple_vdef (stmt)) { diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 2a2364d..8ed834b 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -1691,6 +1691,13 @@ vect_finish_stmt_generation (gimple stmt, gimple vec_stmt, } gimple_set_location (vec_stmt, gimple_location (stmt)); + + /* While EH edges will generally prevent vectorization, stmt might + e.g. be in a must-not-throw region. Ensure newly created stmts + that could throw are part of the same region. */ + int lp_nr = lookup_stmt_eh_lp (stmt); + if (lp_nr != 0 && stmt_could_throw_p (vec_stmt)) + add_stmt_to_eh_lp (vec_stmt, lp_nr); } /* Checks if CALL can be vectorized in type VECTYPE. Returns -- 2.7.4