From patchwork Wed Jun 27 09:34:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 935356 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-480543-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="Rh2Yyhui"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41FySF3tZ9z9s2R for ; Wed, 27 Jun 2018 19:35:09 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:references:date:in-reply-to:message-id :mime-version:content-type; q=dns; s=default; b=XJiVGMO/r9ZoAqAF 6quyh3C24sOMtJT9B9CXHy7Qu0PR2E1zRbl8+aggzr9g7lPqZy1wZo7tD7JOceWM Ul90j3x8LaceVblNFs5Cyv55bl92XMAZIX1epYsSDRpHWCZE791kCtR3jXLs/MC6 5vGT1xiCGCtsDZquQof9XNUV7Zw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:references:date:in-reply-to:message-id :mime-version:content-type; s=default; bh=zV0VFKPBy2clNY/1GYL5qp +Rok0=; b=Rh2Yyhui6nUSatApF1qwjcGWpi7q5LM+fxQagTaGZgPOEU3jSHC2I8 KPi/U7Kiw/rfelNKAqwx1Ea6oUfel2eTY+3TdprWB4azcCpNshZg5ifnpb5fNGVR H0XSgkogI9qdNoDPWNMRnf0aCNhFo+/39SkHzcukAjl+6KHbJQRRc= Received: (qmail 116895 invoked by alias); 27 Jun 2018 09:34:53 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 116777 invoked by uid 89); 27 Jun 2018 09:34:52 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, SPF_PASS autolearn=ham version=3.3.2 spammy=participate X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 27 Jun 2018 09:34:49 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id AB36B80D; Wed, 27 Jun 2018 02:34:48 -0700 (PDT) Received: from localhost (unknown [10.32.98.107]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 0F7FA3F5AD; Wed, 27 Jun 2018 02:34:47 -0700 (PDT) From: Richard Sandiford To: Richard Biener Mail-Followup-To: Richard Biener , GCC Patches , richard.sandiford@arm.com Cc: GCC Patches Subject: [9b/n] PR85694: Make vect_is_simple_use look through pattern statements References: <87d0wof858.fsf@arm.com> <87r2l1eoxk.fsf@arm.com> Date: Wed, 27 Jun 2018 10:34:46 +0100 In-Reply-To: <87r2l1eoxk.fsf@arm.com> (Richard Sandiford's message of "Wed, 20 Jun 2018 11:24:07 +0100") Message-ID: <87r2ksbmix.fsf_-_@arm.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) MIME-Version: 1.0 Richard Sandiford writes: > Richard Biener writes: >> On Mon, Jun 18, 2018 at 5:04 PM Richard Sandiford >> wrote: >>> >>> When following the definitions of SSA names, some recognisers >>> already cope with statements that have been replaced by patterns. >>> This patch makes that happen automatically for users of >>> type_conversion_p and vect_get_internal_def. It also adds >>> a vect_look_through_pattern helper that can be used directly. >>> >>> The reason for doing this is that the main patch for PR85694 >>> makes over_widening handle more general cases. These over-widened >>> patterns can still be useful when matching later statements; >>> e.g. an overwidened MULT_EXPR could be the input to a DOT_PROD_EXPR. >>> >>> The patch doesn't do anything with the STMT_VINFO_IN_PATTERN_P checks >>> in vect_recog_over_widening_pattern or vect_recog_widen_shift_pattern >>> since later patches rewrite them anyway. >>> >>> Doing this fixed an XFAIL in vect-reduc-dot-u16b.c. >>> >>> Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? >> >> Hmm. It seems to me that *def_stmt for vect_is_simple_use should >> eventually be the pattern def given the vectype overload takes the >> vectype from the pattern def already but oddly enough the >> DEF_TYPE is taken from the non-pattern stmt. >> >> I wonder which callers look at def_stmt at all (and how...) >> >> I guess swapping the def_stmt and dt arguments and adding yet another >> overload to remove all unused &def_stmt args might this easier to review... >> >> So - I'm suggesting to change vect_is_simple_use. > > OK, I'll try that. Might end up being its own mini-series. :-) And here's the second and final part: make vect_is_simple_use check whether a defining statement has been replaced by a pattern statement, and if so return the pattern statement instead. Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? Richard 2018-06-14 Richard Sandiford gcc/ * tree-vect-loop.c (vectorizable_reduction): Assert that the phi is not a pattern statement and has not been replaced by a pattern statement. * tree-vect-patterns.c (type_conversion_p): Don't check STMT_VINFO_IN_PATTERN_P. (vect_recog_vector_vector_shift_pattern): Likewise. (vect_recog_dot_prod_pattern): Expect vect_is_simple_use to return the pattern statement rather than the original statement; check directly for a WIDEN_MULT_EXPR here. * tree-vect-slp.c (vect_get_and_check_slp_defs): Expect vect_is_simple_use to return the pattern statement rather than the original statement; use is_pattern_stmt_p to check for such a pattern statement. * tree-vect-stmts.c (process_use): Expect vect_is_simple_use to return the pattern statement rather than the original statement; don't do the same transformation here. (vect_is_simple_use): If the defining statement has been replaced by a pattern statement, return the pattern statement instead. Remove the corresponding (local) transformation from the vectype overload. gcc/testsuite/ * gcc.dg/vect/vect-reduc-dot-u16b.c: Remove xfail and update the test for vectorization along the lines described in the comment. Index: gcc/tree-vect-loop.c =================================================================== --- gcc/tree-vect-loop.c 2018-06-27 10:27:31.782458413 +0100 +++ gcc/tree-vect-loop.c 2018-06-27 10:27:34.490434751 +0100 @@ -6482,6 +6482,8 @@ vectorizable_reduction (gimple *stmt, gi } stmt_vec_info reduc_def_info = vinfo_for_stmt (reduc_def_stmt); + /* PHIs should not participate in patterns. */ + gcc_assert (!STMT_VINFO_RELATED_STMT (reduc_def_info)); enum vect_reduction_type v_reduc_type = STMT_VINFO_REDUC_TYPE (reduc_def_info); gimple *tmp = STMT_VINFO_REDUC_DEF (reduc_def_info); Index: gcc/tree-vect-patterns.c =================================================================== --- gcc/tree-vect-patterns.c 2018-06-27 10:27:31.782458413 +0100 +++ gcc/tree-vect-patterns.c 2018-06-27 10:27:34.490434751 +0100 @@ -193,13 +193,6 @@ type_conversion_p (tree name, gimple *us if (!*def_stmt) return false; - if (dt == vect_internal_def) - { - stmt_vec_info def_vinfo = vinfo_for_stmt (*def_stmt); - if (STMT_VINFO_IN_PATTERN_P (def_vinfo)) - return false; - } - if (!is_gimple_assign (*def_stmt)) return false; @@ -383,20 +376,11 @@ vect_recog_dot_prod_pattern (vec (mult_vinfo->stmt); - if (!mult || gimple_assign_rhs_code (mult) != MULT_EXPR) + if (!mult) return NULL; - if (STMT_VINFO_IN_PATTERN_P (mult_vinfo)) + if (gimple_assign_rhs_code (mult) == WIDEN_MULT_EXPR) { /* Has been detected as a widening multiplication? */ - - mult = dyn_cast (STMT_VINFO_RELATED_STMT (mult_vinfo)); - if (!mult || gimple_assign_rhs_code (mult) != WIDEN_MULT_EXPR) - return NULL; - STMT_VINFO_PATTERN_DEF_SEQ (stmt_vinfo) - = STMT_VINFO_PATTERN_DEF_SEQ (mult_vinfo); - mult_vinfo = vinfo_for_stmt (mult); - gcc_assert (mult_vinfo); - gcc_assert (STMT_VINFO_DEF_TYPE (mult_vinfo) == vect_internal_def); oprnd00 = gimple_assign_rhs1 (mult); oprnd01 = gimple_assign_rhs2 (mult); } @@ -406,6 +390,9 @@ vect_recog_dot_prod_pattern (vec (def_vinfo->stmt); - if (!STMT_VINFO_IN_PATTERN_P (def_vinfo) - && def_stmt - && gimple_assign_cast_p (def_stmt)) + if (def_stmt && gimple_assign_cast_p (def_stmt)) { tree rhs1 = gimple_assign_rhs1 (def_stmt); if (TYPE_MODE (TREE_TYPE (rhs1)) == TYPE_MODE (TREE_TYPE (oprnd0)) Index: gcc/tree-vect-slp.c =================================================================== --- gcc/tree-vect-slp.c 2018-06-27 10:27:31.782458413 +0100 +++ gcc/tree-vect-slp.c 2018-06-27 10:27:34.490434751 +0100 @@ -365,11 +365,9 @@ vect_get_and_check_slp_defs (vec_info *v from the pattern. Check that all the stmts of the node are in the pattern. */ if (def_stmt && gimple_bb (def_stmt) - && vect_stmt_in_region_p (vinfo, def_stmt) - && vinfo_for_stmt (def_stmt) - && STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (def_stmt)) - && !STMT_VINFO_RELEVANT (vinfo_for_stmt (def_stmt)) - && !STMT_VINFO_LIVE_P (vinfo_for_stmt (def_stmt))) + && vect_stmt_in_region_p (vinfo, def_stmt) + && vinfo_for_stmt (def_stmt) + && is_pattern_stmt_p (vinfo_for_stmt (def_stmt))) { pattern = true; if (!first && !oprnd_info->first_pattern @@ -398,7 +396,6 @@ vect_get_and_check_slp_defs (vec_info *v return 1; } - def_stmt = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (def_stmt)); dt = STMT_VINFO_DEF_TYPE (vinfo_for_stmt (def_stmt)); if (dt == vect_unknown_def_type) Index: gcc/tree-vect-stmts.c =================================================================== --- gcc/tree-vect-stmts.c 2018-06-27 10:27:31.782458413 +0100 +++ gcc/tree-vect-stmts.c 2018-06-27 10:27:34.490434751 +0100 @@ -506,8 +506,6 @@ process_use (gimple *stmt, tree use, loo if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "reduc-stmt defining reduc-phi in the same nest.\n"); - if (STMT_VINFO_IN_PATTERN_P (dstmt_vinfo)) - dstmt_vinfo = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (dstmt_vinfo)); gcc_assert (STMT_VINFO_RELEVANT (dstmt_vinfo) < vect_used_by_reduction); gcc_assert (STMT_VINFO_LIVE_P (dstmt_vinfo) || STMT_VINFO_RELEVANT (dstmt_vinfo) > vect_unused_in_scope); @@ -10069,8 +10067,6 @@ vect_is_simple_use (tree operand, vec_in } gimple *def_stmt = SSA_NAME_DEF_STMT (operand); - if (def_stmt_out) - *def_stmt_out = def_stmt; if (dump_enabled_p ()) { dump_printf_loc (MSG_NOTE, vect_location, "def_stmt: "); @@ -10082,8 +10078,15 @@ vect_is_simple_use (tree operand, vec_in else { stmt_vec_info stmt_vinfo = vinfo_for_stmt (def_stmt); + if (STMT_VINFO_IN_PATTERN_P (stmt_vinfo)) + { + def_stmt = STMT_VINFO_RELATED_STMT (stmt_vinfo); + stmt_vinfo = vinfo_for_stmt (def_stmt); + } *dt = STMT_VINFO_DEF_TYPE (stmt_vinfo); } + if (def_stmt_out) + *def_stmt_out = def_stmt; if (dump_enabled_p ()) { @@ -10174,12 +10177,6 @@ vect_is_simple_use (tree operand, vec_in || *dt == vect_nested_cycle) { stmt_vec_info stmt_info = vinfo_for_stmt (def_stmt); - - if (STMT_VINFO_IN_PATTERN_P (stmt_info) - && !STMT_VINFO_RELEVANT (stmt_info) - && !STMT_VINFO_LIVE_P (stmt_info)) - stmt_info = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (stmt_info)); - *vectype = STMT_VINFO_VECTYPE (stmt_info); gcc_assert (*vectype != NULL_TREE); } Index: gcc/testsuite/gcc.dg/vect/vect-reduc-dot-u16b.c =================================================================== --- gcc/testsuite/gcc.dg/vect/vect-reduc-dot-u16b.c 2018-06-27 10:27:12.366628072 +0100 +++ gcc/testsuite/gcc.dg/vect/vect-reduc-dot-u16b.c 2018-06-27 10:27:34.490434751 +0100 @@ -10,11 +10,8 @@ #define DOT2 43680 unsigned short X[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); unsigned short Y[N] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__))); -/* short->int->int dot product. - Currently not detected as a dot-product pattern: the multiplication - promotes the ushorts to int, and then the product is promoted to unsigned - int for the addition. Which results in an int->unsigned int cast, which - since no bits are modified in the cast should be trivially vectorizable. */ +/* ushort->int->uint dot product: the multiplication promotes the ushorts + to int, and then the product is converted to uint for the addition. */ __attribute__ ((noinline)) unsigned int foo2(int len) { int i; @@ -47,12 +44,6 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vect_recog_dot_prod_pattern: detected" 1 "vect" { xfail *-*-* } } } */ - -/* Once the dot-product pattern is detected, we expect - that loop to be vectorized on vect_udot_hi targets (targets that support - dot-product of unsigned shorts) and targets that support widening multiplication. */ -/* The induction loop in main is vectorized. */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail *-*-* } } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_pack_trunc } } } */ +/* { dg-final { scan-tree-dump-times "vect_recog_dot_prod_pattern: detected" 1 "vect" } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_pack_trunc || vect_udot_hi } } } } */