From patchwork Mon Jun 13 06:12:32 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ira Rosen X-Patchwork-Id: 1830 Return-Path: Delivered-To: unknown Received: from imap.gmail.com (74.125.47.109) by localhost6.localdomain6 with IMAP4-SSL; 14 Jun 2011 16:45:49 -0000 Delivered-To: patches@linaro.org Received: by 10.52.181.10 with SMTP id ds10cs435537vdc; Sun, 12 Jun 2011 23:12:36 -0700 (PDT) Received: by 10.100.51.8 with SMTP id y8mr4527544any.111.1307945555234; Sun, 12 Jun 2011 23:12:35 -0700 (PDT) Received: from mail-pw0-f50.google.com (mail-pw0-f50.google.com [209.85.160.50]) by mx.google.com with ESMTPS id i7si9589631anh.63.2011.06.12.23.12.33 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 12 Jun 2011 23:12:34 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.160.50 is neither permitted nor denied by best guess record for domain of ira.rosen@linaro.org) client-ip=209.85.160.50; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.160.50 is neither permitted nor denied by best guess record for domain of ira.rosen@linaro.org) smtp.mail=ira.rosen@linaro.org Received: by pwi3 with SMTP id 3so2248373pwi.37 for ; Sun, 12 Jun 2011 23:12:33 -0700 (PDT) MIME-Version: 1.0 Received: by 10.142.152.4 with SMTP id z4mr745019wfd.93.1307945552713; Sun, 12 Jun 2011 23:12:32 -0700 (PDT) Received: by 10.143.93.4 with HTTP; Sun, 12 Jun 2011 23:12:32 -0700 (PDT) Date: Mon, 13 Jun 2011 09:12:32 +0300 Message-ID: Subject: [patch] Fix PR tree-optimization/49352 From: Ira Rosen To: gcc-patches@gcc.gnu.org Cc: jakub@redhat.com, Patch Tracking Hi, This patch fixes PR 49352 by ignoring debug uses in SLP reduction detection. While fixing it Jakub also discovered that an incorrect statement may be analyzed and operands of not commutative operation may be swapped. The patch fixes those as well. Bootstrapped and tested on powerpc64-suse-linux. Committed. Ira ChangeLog: 2011-06-13 Jakub Jelinek Ira Rosen PR tree-optimization/49352 * tree-vect-loop.c (vect_is_slp_reduction): Don't count debug uses at all, make sure loop_use_stmt after the loop is a def stmt of a used SSA_NAME that is the only one defined inside of the loop. Don't check for COND_EXPR and GIMPLE_BINARY_RHS. (vect_is_simple_reduction_1): Call vect_is_slp_reduction only if check_reduction is true. 2011-06-13 Jakub Jelinek Ira Rosen PR tree-optimization/49352 * gcc.dg/vect/pr49352.c: New test. Index: testsuite/gcc.dg/vect/pr49352.c =================================================================== --- testsuite/gcc.dg/vect/pr49352.c (revision 0) +++ testsuite/gcc.dg/vect/pr49352.c (revision 0) @@ -0,0 +1,14 @@ +/* PR tree-optimization/49352 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -fcompare-debug" } */ + +int +foo (int *x, int *y, int n) +{ + int i, j; + int dot = 0; + for (i = 0; i < n; i++) + for (j = 0; j < 2; j++) + dot += *(x++) * *(y++); + return dot; +} Index: tree-vect-loop.c =================================================================== --- tree-vect-loop.c (revision 174981) +++ tree-vect-loop.c (working copy) @@ -1710,12 +1710,12 @@ vect_is_slp_reduction (loop_vec_info loop_info, gi struct loop *loop = (gimple_bb (phi))->loop_father; struct loop *vect_loop = LOOP_VINFO_LOOP (loop_info); enum tree_code code; - gimple current_stmt = NULL, use_stmt = NULL, first, next_stmt; + gimple current_stmt = NULL, loop_use_stmt = NULL, first, next_stmt; stmt_vec_info use_stmt_info, current_stmt_info; tree lhs; imm_use_iterator imm_iter; use_operand_p use_p; - int nloop_uses, size = 0, nuses; + int nloop_uses, size = 0; bool found = false; if (loop != vect_loop) @@ -1726,66 +1726,68 @@ vect_is_slp_reduction (loop_vec_info loop_info, gi while (1) { nloop_uses = 0; - nuses = 0; FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs) { - use_stmt = USE_STMT (use_p); - nuses++; + gimple use_stmt = USE_STMT (use_p); if (is_gimple_debug (use_stmt)) continue; + use_stmt = USE_STMT (use_p); + /* Check if we got back to the reduction phi. */ - if (gimple_code (use_stmt) == GIMPLE_PHI - && use_stmt == phi) + if (use_stmt == phi) { + loop_use_stmt = use_stmt; found = true; break; } if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)) && vinfo_for_stmt (use_stmt) - && !is_pattern_stmt_p (vinfo_for_stmt (use_stmt)) - && use_stmt != first_stmt) - nloop_uses++; + && !STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (use_stmt))) + { + loop_use_stmt = use_stmt; + nloop_uses++; + } if (nloop_uses > 1) return false; } - /* We reached a statement with no uses. */ - if (nuses == 0) - return false; - if (found) break; + /* We reached a statement with no loop uses. */ + if (nloop_uses == 0) + return false; + /* This is a loop exit phi, and we haven't reached the reduction phi. */ - if (gimple_code (use_stmt) == GIMPLE_PHI) + if (gimple_code (loop_use_stmt) == GIMPLE_PHI) return false; - if (!is_gimple_assign (use_stmt) - || code != gimple_assign_rhs_code (use_stmt) - || !flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))) + if (!is_gimple_assign (loop_use_stmt) + || code != gimple_assign_rhs_code (loop_use_stmt) + || !flow_bb_inside_loop_p (loop, gimple_bb (loop_use_stmt))) return false; /* Insert USE_STMT into reduction chain. */ - use_stmt_info = vinfo_for_stmt (use_stmt); + use_stmt_info = vinfo_for_stmt (loop_use_stmt); if (current_stmt) { current_stmt_info = vinfo_for_stmt (current_stmt); - GROUP_NEXT_ELEMENT (current_stmt_info) = use_stmt; + GROUP_NEXT_ELEMENT (current_stmt_info) = loop_use_stmt; GROUP_FIRST_ELEMENT (use_stmt_info) = GROUP_FIRST_ELEMENT (current_stmt_info); } else - GROUP_FIRST_ELEMENT (use_stmt_info) = use_stmt; + GROUP_FIRST_ELEMENT (use_stmt_info) = loop_use_stmt; - lhs = gimple_assign_lhs (use_stmt); - current_stmt = use_stmt; + lhs = gimple_assign_lhs (loop_use_stmt); + current_stmt = loop_use_stmt; size++; } - if (!found || use_stmt != phi || size < 2) + if (!found || loop_use_stmt != phi || size < 2) return false; /* Swap the operands, if needed, to make the reduction operand be the second @@ -1794,75 +1796,70 @@ vect_is_slp_reduction (loop_vec_info loop_info, gi next_stmt = GROUP_FIRST_ELEMENT (vinfo_for_stmt (current_stmt)); while (next_stmt) { - if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS) + if (gimple_assign_rhs2 (next_stmt) == lhs) { - if (gimple_assign_rhs2 (next_stmt) == lhs) - { - tree op = gimple_assign_rhs1 (next_stmt); - gimple def_stmt = NULL; + tree op = gimple_assign_rhs1 (next_stmt); + gimple def_stmt = NULL; - if (TREE_CODE (op) == SSA_NAME) - def_stmt = SSA_NAME_DEF_STMT (op); + if (TREE_CODE (op) == SSA_NAME) + def_stmt = SSA_NAME_DEF_STMT (op); - /* Check that the other def is either defined in the loop - ("vect_internal_def"), or it's an induction (defined by a - loop-header phi-node). */ - if (code == COND_EXPR - || (def_stmt - && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) - && (is_gimple_assign (def_stmt) - || is_gimple_call (def_stmt) - || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) - == vect_induction_def - || (gimple_code (def_stmt) == GIMPLE_PHI - && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) + /* Check that the other def is either defined in the loop + ("vect_internal_def"), or it's an induction (defined by a + loop-header phi-node). */ + if (def_stmt + && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) + && (is_gimple_assign (def_stmt) + || is_gimple_call (def_stmt) + || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) + == vect_induction_def + || (gimple_code (def_stmt) == GIMPLE_PHI + && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) == vect_internal_def - && !is_loop_header_bb_p (gimple_bb (def_stmt)))))) - { - lhs = gimple_assign_lhs (next_stmt); - next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt)); - continue; - } - - return false; - } - else + && !is_loop_header_bb_p (gimple_bb (def_stmt))))) { - tree op = gimple_assign_rhs2 (next_stmt); - gimple def_stmt = NULL; + lhs = gimple_assign_lhs (next_stmt); + next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt)); + continue; + } - if (TREE_CODE (op) == SSA_NAME) - def_stmt = SSA_NAME_DEF_STMT (op); + return false; + } + else + { + tree op = gimple_assign_rhs2 (next_stmt); + gimple def_stmt = NULL; - /* Check that the other def is either defined in the loop - ("vect_internal_def"), or it's an induction (defined by a - loop-header phi-node). */ - if (code == COND_EXPR - || (def_stmt - && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) - && (is_gimple_assign (def_stmt) - || is_gimple_call (def_stmt) - || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) + if (TREE_CODE (op) == SSA_NAME) + def_stmt = SSA_NAME_DEF_STMT (op); + + /* Check that the other def is either defined in the loop + ("vect_internal_def"), or it's an induction (defined by a + loop-header phi-node). */ + if (def_stmt + && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) + && (is_gimple_assign (def_stmt) + || is_gimple_call (def_stmt) + || STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) == vect_induction_def - || (gimple_code (def_stmt) == GIMPLE_PHI - && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) + || (gimple_code (def_stmt) == GIMPLE_PHI + && STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)) == vect_internal_def - && !is_loop_header_bb_p (gimple_bb (def_stmt)))))) + && !is_loop_header_bb_p (gimple_bb (def_stmt))))) + { + if (vect_print_dump_info (REPORT_DETAILS)) { - if (vect_print_dump_info (REPORT_DETAILS)) - { - fprintf (vect_dump, "swapping oprnds: "); - print_gimple_stmt (vect_dump, next_stmt, 0, TDF_SLIM); - } - - swap_tree_operands (next_stmt, - gimple_assign_rhs1_ptr (next_stmt), - gimple_assign_rhs2_ptr (next_stmt)); - mark_symbols_for_renaming (next_stmt); + fprintf (vect_dump, "swapping oprnds: "); + print_gimple_stmt (vect_dump, next_stmt, 0, TDF_SLIM); } - else - return false; + + swap_tree_operands (next_stmt, + gimple_assign_rhs1_ptr (next_stmt), + gimple_assign_rhs2_ptr (next_stmt)); + mark_symbols_for_renaming (next_stmt); } + else + return false; } lhs = gimple_assign_lhs (next_stmt); @@ -2273,7 +2270,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_inf } /* Try to find SLP reduction chain. */ - if (vect_is_slp_reduction (loop_info, phi, def_stmt)) + if (check_reduction && vect_is_slp_reduction (loop_info, phi, def_stmt)) { if (vect_print_dump_info (REPORT_DETAILS)) report_vect_op (def_stmt, "reduction: detected reduction chain: ");