This fixes SLP reduction of two-operator operations by marking those not supported. In fact any live lane out of such an operation cannot be code-generated correctly.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. This is for GCC 10 only, trunk gets the new testcase only. Richard. 2020-08-31 Richard Biener <rguent...@suse.de> PR tree-optimization/96854 * tree-vect-loop.c (vectorizable_live_operation): Disallow SLP_TREE_TWO_OPERATORS nodes. * gcc.dg/vect/pr96854.c: New testcase. --- gcc/testsuite/gcc.dg/vect/pr96854.c | 20 ++++++++++++++++++++ gcc/tree-vect-loop.c | 5 +++++ 2 files changed, 25 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/vect/pr96854.c diff --git a/gcc/testsuite/gcc.dg/vect/pr96854.c b/gcc/testsuite/gcc.dg/vect/pr96854.c new file mode 100644 index 00000000000..e3980d41303 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr96854.c @@ -0,0 +1,20 @@ +/* { dg-additional-options "-ffast-math" } */ + +double _Complex __attribute__((noipa)) +foo (double _Complex acc, const double _Complex *x, const double _Complex* y, int N) +{ + for (int c = 0; c < N; ++c) + acc -= x[c] * y[c]; + return acc; +} + +int +main() +{ + static const double _Complex y[] = { 1, 2, }; + static const double _Complex x[] = { 1, 3, }; + double _Complex ref = foo (0, x, y, 2); + if (__builtin_creal (ref) != -7.) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index b6c3faeae51..29071630327 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -7867,6 +7867,11 @@ vectorizable_live_operation (stmt_vec_info stmt_info, gcc_assert (STMT_VINFO_LIVE_P (stmt_info)); + /* Due to how we generate code for SLP_TREE_TWO_OPERATORS we cannot + vectorize live operations out of it. */ + if (slp_node && SLP_TREE_TWO_OPERATORS (slp_node)) + return false; + /* If a stmt of a reduction is live, vectorize it via vect_create_epilog_for_reduction. vectorizable_reduction assessed validity so just trigger the transform here. */ -- 2.26.2