From patchwork Mon May 9 05:11:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: liuhongt X-Patchwork-Id: 53614 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3514C385734D for ; Mon, 9 May 2022 05:11:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3514C385734D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1652073108; bh=u+ex/P2FTlzzx0x5+s18u4pFIhAZ2ysqlNGaZBa2jyo=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=YGtf4Fw19TR1JsBOKxiw7NafMzT3/dAToIkH/S7qBEKglPbJRB7t1wS7aP2/EyLYp feF+Ff14MOxGQGHbTer5MzMyYf88SvMLmvfka9Ixvn0sWfe7LvwYceKI9zkWLoIo6x xNlu/8AgS/krlUJnQ6pach3nMV1qofydOw1E94ys= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mga06.intel.com (mga06b.intel.com [134.134.136.31]) by sourceware.org (Postfix) with ESMTPS id A9EA23858C54 for ; Mon, 9 May 2022 05:11:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A9EA23858C54 X-IronPort-AV: E=McAfee;i="6400,9594,10341"; a="329530183" X-IronPort-AV: E=Sophos;i="5.91,210,1647327600"; d="scan'208";a="329530183" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga104.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 May 2022 22:11:14 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.91,210,1647327600"; d="scan'208";a="591110872" Received: from scymds01.sc.intel.com ([10.148.94.138]) by orsmga008.jf.intel.com with ESMTP; 08 May 2022 22:11:14 -0700 Received: from shliclel051.sh.intel.com (shliclel051.sh.intel.com [10.239.236.51]) by scymds01.sc.intel.com with ESMTP id 2495BCtU018914; Sun, 8 May 2022 22:11:13 -0700 To: gcc-patches@gcc.gnu.org Subject: [PATCH v2] Strip of a vector load which is only used partially. Date: Mon, 9 May 2022 13:11:12 +0800 Message-Id: <20220509051112.80162-1-hongtao.liu@intel.com> X-Mailer: git-send-email 2.18.1 In-Reply-To: References: X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: liuhongt via Gcc-patches From: liuhongt Reply-To: liuhongt Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Here's adjused patch. Ok for trunk? Optimize _4 = VEC_PERM_EXPR <_1, _1, { 4, 5, 6, 7, 4, 5, 6, 7 }>; _5 = BIT_FIELD_REF <_4, 128, 0>; to _5 = BIT_FIELD_REF <_1, 128, 128>; gcc/ChangeLog: PR tree-optimization/102583 * tree-ssa-forwprop.cc (simplify_bitfield_ref): Extended to a contiguous stride in the VEC_PERM_EXPR. gcc/testsuite/ChangeLog: * gcc.target/i386/pr102583.c: New test. * gcc.target/i386/pr92645-2.c: Adjust testcase. * gcc.target/i386/pr92645-3.c: Ditto. --- gcc/testsuite/gcc.target/i386/pr102583.c | 30 ++++++++ gcc/testsuite/gcc.target/i386/pr92645-2.c | 4 +- gcc/testsuite/gcc.target/i386/pr92645-3.c | 4 +- gcc/tree-ssa-forwprop.cc | 89 ++++++++++++++++------- 4 files changed, 96 insertions(+), 31 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr102583.c diff --git a/gcc/testsuite/gcc.target/i386/pr102583.c b/gcc/testsuite/gcc.target/i386/pr102583.c new file mode 100644 index 00000000000..4ef2f296d0c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr102583.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-mavx512f -O2" } */ +/* { dg-final { scan-assembler-times {(?n)vcvtdq2ps[ \t]+32\(%.*%ymm} 1 } } */ +/* { dg-final { scan-assembler-times {(?n)vcvtdq2ps[ \t]+16\(%.*%xmm} 1 } } */ +/* { dg-final { scan-assembler-times {(?n)vmovq[ \t]+16\(%.*%xmm} 1 { target { ! ia32 } } } } */ +/* { dg-final { scan-assembler-not {(?n)vpermd[ \t]+.*%zmm} } } */ + +typedef int v16si __attribute__((vector_size(64))); +typedef float v8sf __attribute__((vector_size(32))); +typedef float v4sf __attribute__((vector_size(16))); +typedef float v2sf __attribute__((vector_size(8))); + +v8sf part (v16si *srcp) +{ + v16si src = *srcp; + return (v8sf) { (float)src[8], (float) src[9], (float)src[10], (float)src[11], + (float)src[12], (float)src[13], (float)src[14], (float)src[15] }; +} + +v4sf part1 (v16si *srcp) +{ + v16si src = *srcp; + return (v4sf) { (float)src[4], (float)src[5], (float)src[6], (float)src[7] }; +} + +v2sf part2 (v16si *srcp) +{ + v16si src = *srcp; + return (v2sf) { (float)src[4], (float)src[5] }; +} diff --git a/gcc/testsuite/gcc.target/i386/pr92645-2.c b/gcc/testsuite/gcc.target/i386/pr92645-2.c index d34ed3aa8e5..f0608de938a 100644 --- a/gcc/testsuite/gcc.target/i386/pr92645-2.c +++ b/gcc/testsuite/gcc.target/i386/pr92645-2.c @@ -29,6 +29,6 @@ void odd (v2si *dst, v4si *srcp) } /* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 4 "cddce1" } } */ -/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 3 "cddce1" } } */ +/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 3 "cddce1" { xfail *-*-* } } } */ /* Ideally highpart extraction would elide the permutation as well. */ -/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 2 "cddce1" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 2 "cddce1" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr92645-3.c b/gcc/testsuite/gcc.target/i386/pr92645-3.c index 9c08c9fb632..691011195c9 100644 --- a/gcc/testsuite/gcc.target/i386/pr92645-3.c +++ b/gcc/testsuite/gcc.target/i386/pr92645-3.c @@ -32,6 +32,6 @@ void odd (v4sf *dst, v8si *srcp) /* Four conversions, on the smaller vector type, to not convert excess elements. */ /* { dg-final { scan-tree-dump-times " = \\\(vector\\\(4\\\) float\\\)" 4 "cddce1" } } */ -/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 3 "cddce1" } } */ +/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 3 "cddce1" { xfail *-*-* } } } */ /* Ideally highpart extraction would elide the VEC_PERM_EXPR as well. */ -/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 2 "cddce1" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 2 "cddce1" } } */ diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc index 484491fa1c5..f91f738895d 100644 --- a/gcc/tree-ssa-forwprop.cc +++ b/gcc/tree-ssa-forwprop.cc @@ -2334,8 +2334,10 @@ simplify_bitfield_ref (gimple_stmt_iterator *gsi) gimple *stmt = gsi_stmt (*gsi); gimple *def_stmt; tree op, op0, op1; - tree elem_type; - unsigned idx, size; + tree elem_type, type; + tree p, m, tem; + unsigned HOST_WIDE_INT nelts; + unsigned idx, size, elem_size; enum tree_code code; op = gimple_assign_rhs1 (stmt); @@ -2353,42 +2355,75 @@ simplify_bitfield_ref (gimple_stmt_iterator *gsi) op1 = TREE_OPERAND (op, 1); code = gimple_assign_rhs_code (def_stmt); elem_type = TREE_TYPE (TREE_TYPE (op0)); - if (TREE_TYPE (op) != elem_type) + type = TREE_TYPE (op); + /* Also hanlde vector type. + .i.e. + _7 = VEC_PERM_EXPR <_1, _1, { 2, 3, 2, 3 }>; + _11 = BIT_FIELD_REF <_7, 64, 0>; + + to + + _11 = BIT_FIELD_REF <_1, 64, 64>. */ + if (type != elem_type + && (!VECTOR_TYPE_P (type) || TREE_TYPE (type) != elem_type)) return false; - size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type)); + elem_size = size = TREE_INT_CST_LOW (TYPE_SIZE (type)); if (maybe_ne (bit_field_size (op), size)) return false; - if (code == VEC_PERM_EXPR - && constant_multiple_p (bit_field_offset (op), size, &idx)) + if (code != VEC_PERM_EXPR + || !constant_multiple_p (bit_field_offset (op), size, &idx)) + return false; + + m = gimple_assign_rhs3 (def_stmt); + if (TREE_CODE (m) != VECTOR_CST + || !VECTOR_CST_NELTS (m).is_constant (&nelts)) + return false; + + /* One element. */ + if (type == elem_type) + idx = TREE_INT_CST_LOW (VECTOR_CST_ELT (m, idx)); + else { - tree p, m, tem; - unsigned HOST_WIDE_INT nelts; - m = gimple_assign_rhs3 (def_stmt); - if (TREE_CODE (m) != VECTOR_CST - || !VECTOR_CST_NELTS (m).is_constant (&nelts)) + elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type)); + unsigned nelts_op; + if (!constant_multiple_p (bit_field_size (op), elem_size, &nelts_op)) return false; - idx = TREE_INT_CST_LOW (VECTOR_CST_ELT (m, idx)); - idx %= 2 * nelts; - if (idx < nelts) - { - p = gimple_assign_rhs1 (def_stmt); - } - else + unsigned start = TREE_INT_CST_LOW (vector_cst_elt (m, idx)); + unsigned end = TREE_INT_CST_LOW (vector_cst_elt (m, idx + nelts_op - 1)); + /* Be in the same vector. */ + if ((start < nelts) != (end < nelts)) + return false; + for (unsigned HOST_WIDE_INT i = 1; i != nelts_op; i++) { - p = gimple_assign_rhs2 (def_stmt); - idx -= nelts; + /* Continuous area. */ + if (TREE_INT_CST_LOW (vector_cst_elt (m, idx + i)) - 1 + != TREE_INT_CST_LOW (vector_cst_elt (m, idx + i - 1))) + return false; } - tem = build3 (BIT_FIELD_REF, TREE_TYPE (op), - unshare_expr (p), op1, bitsize_int (idx * size)); - gimple_assign_set_rhs1 (stmt, tem); - fold_stmt (gsi); - update_stmt (gsi_stmt (*gsi)); - return true; + /* Alignment not worse than before. */ + unsigned dest_align = TREE_INT_CST_LOW (TYPE_SIZE (type)); + if (start * elem_size % dest_align) + return false; + idx = start; } - return false; + idx %= 2 * nelts; + if (idx < nelts) + p = gimple_assign_rhs1 (def_stmt); + else + { + p = gimple_assign_rhs2 (def_stmt); + idx -= nelts; + } + + tem = build3 (BIT_FIELD_REF, TREE_TYPE (op), + unshare_expr (p), op1, bitsize_int (idx * elem_size)); + gimple_assign_set_rhs1 (stmt, tem); + fold_stmt (gsi); + update_stmt (gsi_stmt (*gsi)); + return true; } /* Determine whether applying the 2 permutations (mask1 then mask2)