From: Jakub Jelinek Date: Thu, 3 Mar 2016 14:32:15 +0000 (+0100) Subject: re PR target/70021 (Test miscompiled with -O3 option for -march=core-avx2.) X-Git-Tag: basepoints/gcc-7~606 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=97ecdb46b1261d34e015df1f6eff20e069ca9bbf;p=thirdparty%2Fgcc.git re PR target/70021 (Test miscompiled with -O3 option for -march=core-avx2.) PR target/70021 * tree-vect-stmts.c (vect_mark_relevant): Remove USED_IN_PATTERN argument, if STMT_VINFO_IN_PATTERN_P (stmt_info), always mark the pattern no matter if it is used just by non-pattern, pattern or mix thereof. (process_use, vect_mark_stmts_to_be_vectorized): Adjust callers. * tree-vect-patterns.c (vect_recog_vector_vector_shift_pattern): If oprnd1 def_stmt is in pattern, don't look through it. * gcc.dg/vect/pr70021.c: New test. * gcc.target/i386/pr70021.c: New test. From-SVN: r233940 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c7b8c172c77b..fb5e396a448f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2016-03-03 Jakub Jelinek + + PR target/70021 + * tree-vect-stmts.c (vect_mark_relevant): Remove USED_IN_PATTERN + argument, if STMT_VINFO_IN_PATTERN_P (stmt_info), always mark + the pattern no matter if it is used just by non-pattern, pattern + or mix thereof. + (process_use, vect_mark_stmts_to_be_vectorized): Adjust callers. + * tree-vect-patterns.c (vect_recog_vector_vector_shift_pattern): If + oprnd1 def_stmt is in pattern, don't look through it. + 2016-03-03 Marek Polacek PR middle-end/70050 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9949f9c11ff8..5ffe64f65f3f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-03-03 Jakub Jelinek + + PR target/70021 + * gcc.dg/vect/pr70021.c: New test. + * gcc.target/i386/pr70021.c: New test. + 2016-03-03 Marek Polacek PR middle-end/70050 diff --git a/gcc/testsuite/gcc.dg/vect/pr70021.c b/gcc/testsuite/gcc.dg/vect/pr70021.c new file mode 100644 index 000000000000..b147fa1598f2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr70021.c @@ -0,0 +1,40 @@ +/* PR target/70021 */ +/* { dg-do run } */ + +#include "tree-vect.h" + +#define N 160 +int a[N]; +unsigned long long int b[N], c[N], d[N], e[N]; + +__attribute__((noinline, noclone)) void +foo (void) +{ + int i; + for (i = 0; i < N; i += 4) + { + unsigned long long int f = (_Bool) b[i]; + unsigned long long int g = c[i] != d[i]; + e[i] = g ^ (a[i] & (g << f)); + } +} + +int +main () +{ + int i; + check_vect (); + for (i = 0; i < N; ++i) + { + a[i] = 1618000128; + b[i] = 10919594786573202791ULL; + c[i] = 2593730175074624973ULL; + d[i] = 7447894520878803661ULL; + e[i] = 14234165565810642243ULL; + } + foo (); + for (i = 0; i < N; ++i) + if (e[i] != ((i & 3) ? 14234165565810642243ULL : 1ULL)) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/pr70021.c b/gcc/testsuite/gcc.target/i386/pr70021.c new file mode 100644 index 000000000000..de6da3451192 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr70021.c @@ -0,0 +1,42 @@ +/* PR target/70021 */ +/* { dg-do run } */ +/* { dg-require-effective-target avx2 } */ +/* { dg-options "-O2 -ftree-vectorize -mavx2 -fdump-tree-vect-details" } */ + +#include "avx2-check.h" + +#define N 160 +int a[N]; +unsigned long long int b[N], c[N], d[N], e[N]; + +__attribute__((noinline, noclone)) void +foo (void) +{ + int i; + for (i = 0; i < N; i += 4) + { + unsigned long long int f = (_Bool) b[i]; + unsigned long long int g = c[i] != d[i]; + e[i] = g ^ (a[i] & (g << f)); + } +} + +void +avx2_test () +{ + int i; + for (i = 0; i < N; ++i) + { + a[i] = 1618000128; + b[i] = 10919594786573202791ULL; + c[i] = 2593730175074624973ULL; + d[i] = 7447894520878803661ULL; + e[i] = 14234165565810642243ULL; + } + foo (); + for (i = 0; i < N; ++i) + if (e[i] != ((i & 3) ? 14234165565810642243ULL : 1ULL)) + __builtin_abort (); +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */ diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 95ce38d5f042..4b3065ebb78d 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -2090,7 +2090,8 @@ vect_recog_vector_vector_shift_pattern (vec *stmts, return NULL; tree def = NULL_TREE; - if (gimple_assign_cast_p (def_stmt)) + stmt_vec_info def_vinfo = vinfo_for_stmt (def_stmt); + if (!STMT_VINFO_IN_PATTERN_P (def_vinfo) && gimple_assign_cast_p (def_stmt)) { tree rhs1 = gimple_assign_rhs1 (def_stmt); if (TYPE_MODE (TREE_TYPE (rhs1)) == TYPE_MODE (TREE_TYPE (oprnd0)) diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 182b277973ec..6ac273dc63dc 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -181,8 +181,7 @@ create_array_ref (tree type, tree ptr, struct data_reference *first_dr) static void vect_mark_relevant (vec *worklist, gimple *stmt, - enum vect_relevant relevant, bool live_p, - bool used_in_pattern) + enum vect_relevant relevant, bool live_p) { stmt_vec_info stmt_info = vinfo_for_stmt (stmt); enum vect_relevant save_relevant = STMT_VINFO_RELEVANT (stmt_info); @@ -202,62 +201,22 @@ vect_mark_relevant (vec *worklist, gimple *stmt, stmt itself should be marked. */ if (STMT_VINFO_IN_PATTERN_P (stmt_info)) { - bool found = false; - if (!used_in_pattern) - { - imm_use_iterator imm_iter; - use_operand_p use_p; - gimple *use_stmt; - tree lhs; - loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info); - struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); - - if (is_gimple_assign (stmt)) - lhs = gimple_assign_lhs (stmt); - else - lhs = gimple_call_lhs (stmt); - - /* This use is out of pattern use, if LHS has other uses that are - pattern uses, we should mark the stmt itself, and not the pattern - stmt. */ - if (lhs && TREE_CODE (lhs) == SSA_NAME) - FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs) - { - if (is_gimple_debug (USE_STMT (use_p))) - continue; - use_stmt = USE_STMT (use_p); - - if (!flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))) - continue; - - if (vinfo_for_stmt (use_stmt) - && STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (use_stmt))) - { - found = true; - break; - } - } - } + /* This is the last stmt in a sequence that was detected as a + pattern that can potentially be vectorized. Don't mark the stmt + as relevant/live because it's not going to be vectorized. + Instead mark the pattern-stmt that replaces it. */ - if (!found) - { - /* This is the last stmt in a sequence that was detected as a - pattern that can potentially be vectorized. Don't mark the stmt - as relevant/live because it's not going to be vectorized. - Instead mark the pattern-stmt that replaces it. */ - - pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info); + pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info); - if (dump_enabled_p ()) - dump_printf_loc (MSG_NOTE, vect_location, - "last stmt in pattern. don't mark" - " relevant/live.\n"); - stmt_info = vinfo_for_stmt (pattern_stmt); - gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == stmt); - save_relevant = STMT_VINFO_RELEVANT (stmt_info); - save_live_p = STMT_VINFO_LIVE_P (stmt_info); - stmt = pattern_stmt; - } + if (dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "last stmt in pattern. don't mark" + " relevant/live.\n"); + stmt_info = vinfo_for_stmt (pattern_stmt); + gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == stmt); + save_relevant = STMT_VINFO_RELEVANT (stmt_info); + save_live_p = STMT_VINFO_LIVE_P (stmt_info); + stmt = pattern_stmt; } STMT_VINFO_LIVE_P (stmt_info) |= live_p; @@ -572,8 +531,7 @@ process_use (gimple *stmt, tree use, loop_vec_info loop_vinfo, bool live_p, } } - vect_mark_relevant (worklist, def_stmt, relevant, live_p, - is_pattern_stmt_p (stmt_vinfo)); + vect_mark_relevant (worklist, def_stmt, relevant, live_p); return true; } @@ -630,7 +588,7 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) } if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p)) - vect_mark_relevant (&worklist, phi, relevant, live_p, false); + vect_mark_relevant (&worklist, phi, relevant, live_p); } for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) { @@ -642,7 +600,7 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) } if (vect_stmt_relevant_p (stmt, loop_vinfo, &relevant, &live_p)) - vect_mark_relevant (&worklist, stmt, relevant, live_p, false); + vect_mark_relevant (&worklist, stmt, relevant, live_p); } }