From patchwork Thu Jul 6 16:15:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 116797 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:9f45:0:b0:3ea:f831:8777 with SMTP id v5csp2675830vqx; Thu, 6 Jul 2023 09:18:22 -0700 (PDT) X-Google-Smtp-Source: APBJJlHdDF5wAjtPKRGH5vSXsC//QXivaMbmVciCQtu5rScclCxP6eLgtnFAvI1dOQU0khla4AF5 X-Received: by 2002:a19:5f5d:0:b0:4f9:607a:6508 with SMTP id a29-20020a195f5d000000b004f9607a6508mr1694507lfj.50.1688660302515; Thu, 06 Jul 2023 09:18:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1688660302; cv=none; d=google.com; s=arc-20160816; b=OqHRt8m8PLSkLV/ybojR5Y3T9PG7epJBOOnPp/YmZS6oBLFs7u+zXHFl/T9grc8Ag9 fWsLCr2q64UbNeAKy3TOsVzdSfc3AfoUb3Fga9UPnAfipQht5+jPsT1orASFjTZzJM91 gns/YpiPNWZ3i2yJOEG56IE0CcSC0thbc4QhbFCtN71pOcQjsZw8UnsOErAMepPoRWLZ uKUwlGcEYlkgvDge9qvMRIK9B5S0WVi17sToZt+8G9n7yj66kBVviGaGeGVmuUlm7Ugh dSpgCxrD+kTUsEOYbIweJltO88SQwz2PGztAjwx3dM1Y7hukpHH6cpnR4gz7Enpg221p L+3w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:message-id:date:subject:cc :to:dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=PfCNFeRXumxuIBa2aEaPS3TXmMQGT4kTDcdtEaOkHFM=; fh=gb72vXsYmGQORe6VgkirOjP90Kr5RTqNYHCUGFv0C4o=; b=uGKoiGKpt+6PojuOLx75lw4mBxyKlzQ9ruIAP0c0unRvAi3E808ZptY149VSN/ahr2 KRQG8utjGvCyCoTqJs8Vpp2PluoSDSWV/N4uhQtybi2bP/hZKLwhxv7WyhcVdf2AyPyi PKH9dEGHFVwtr5z6CshxTRMSW1KljlyHi+aGhxbkeblMG1tUru7bH5LKs7lNfgefv5B2 63STHDT8N/aCHADA9thMb2sefYHnLvJveSdhUjH/NgysxoP+zvG9FTjmWuyhvjfJHqkE JyyJDclpaf3GpohfzzLrOefHk25TUPoeaeLkr30+nxgvKxwYBn0BRHCQXvs7lO93+/OB NecQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=WLsLEdoW; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id k4-20020a1709061c0400b00977e918e260si25076ejg.618.2023.07.06.09.18.22 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Jul 2023 09:18:22 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=WLsLEdoW; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BF2D5385771F for ; Thu, 6 Jul 2023 16:18:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BF2D5385771F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1688660299; bh=PfCNFeRXumxuIBa2aEaPS3TXmMQGT4kTDcdtEaOkHFM=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=WLsLEdoWB9Z4ZinDqkV7vK10H6dm6bcAu1kfqCxdrgXAWmZXLy61S2dS1VnNJ5ATp plhzJgUKXYXtTvQXnuggexbZjnM7F0Ujg0NwlDXzeoEYheKD5U2GtknlL93rTngusq WjjhLOyLGQnaXOzPMZHqJbsrvVu3d2N5+fA34Trg= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from xry111.site (xry111.site [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id C26F93858C2D for ; Thu, 6 Jul 2023 16:17:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C26F93858C2D Received: from stargazer.. (unknown [IPv6:240e:358:110b:4200:dc73:854d:832e:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id 8E8F4663BE; Thu, 6 Jul 2023 12:17:30 -0400 (EDT) To: gcc-patches@gcc.gnu.org Cc: Andre Vieira , Richard Biener , Jakub Jelinek , Hongtao Liu , Xi Ruoyao Subject: [PATCH] vect: Fix vectorized BIT_FIELD_REF for signed bit-fields [PR110557] Date: Fri, 7 Jul 2023 00:15:22 +0800 Message-ID: <20230706161521.6094-2-xry111@xry111.site> X-Mailer: git-send-email 2.41.0 MIME-Version: 1.0 X-Spam-Status: No, score=-8.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, LIKELY_SPAM_FROM, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Xi Ruoyao via Gcc-patches From: Xi Ruoyao Reply-To: Xi Ruoyao Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1770688665645460498?= X-GMAIL-MSGID: =?utf-8?q?1770688665645460498?= If a bit-field is signed and it's wider than the output type, we must ensure the extracted result sign-extended. But this was not handled correctly. For example: int x : 8; long y : 55; bool z : 1; The vectorized extraction of y was: vect__ifc__49.29_110 = MEM [(struct Item *)vectp_a.27_108]; vect_patt_38.30_112 = vect__ifc__49.29_110 & { 9223372036854775552, 9223372036854775552 }; vect_patt_39.31_113 = vect_patt_38.30_112 >> 8; vect_patt_40.32_114 = VIEW_CONVERT_EXPR(vect_patt_39.31_113); This is obviously incorrect. This pach has implemented it as: vect__ifc__25.16_62 = MEM [(struct Item *)vectp_a.14_60]; vect_patt_31.17_63 = VIEW_CONVERT_EXPR(vect__ifc__25.16_62); vect_patt_32.18_64 = vect_patt_31.17_63 << 1; vect_patt_33.19_65 = vect_patt_32.18_64 >> 9; gcc/ChangeLog: PR tree-optimization/110557 * tree-vect-patterns.cc (vect_recog_bitfield_ref_pattern): Ensure the output sign-extended if necessary. gcc/testsuite/ChangeLog: PR tree-optimization/110557 * g++.dg/vect/pr110557.cc: New test. --- Bootstrapped and regtested on x86_64-linux-gnu. Ok for trunk and gcc-13 branch? gcc/testsuite/g++.dg/vect/pr110557.cc | 37 +++++++++++++++++ gcc/tree-vect-patterns.cc | 58 ++++++++++++++++++++------- 2 files changed, 81 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/g++.dg/vect/pr110557.cc diff --git a/gcc/testsuite/g++.dg/vect/pr110557.cc b/gcc/testsuite/g++.dg/vect/pr110557.cc new file mode 100644 index 00000000000..e1fbe1caac4 --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/pr110557.cc @@ -0,0 +1,37 @@ +// { dg-additional-options "-mavx" { target { avx_runtime } } } + +static inline long +min (long a, long b) +{ + return a < b ? a : b; +} + +struct Item +{ + int x : 8; + long y : 55; + bool z : 1; +}; + +__attribute__ ((noipa)) long +test (Item *a, int cnt) +{ + long size = 0; + for (int i = 0; i < cnt; i++) + size = min ((long)a[i].y, size); + return size; +} + +int +main () +{ + struct Item items[] = { + { 1, -1 }, + { 2, -2 }, + { 3, -3 }, + { 4, -4 }, + }; + + if (test (items, 4) != -4) + __builtin_trap (); +} diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc index 1bc36b043a0..20412c27ead 100644 --- a/gcc/tree-vect-patterns.cc +++ b/gcc/tree-vect-patterns.cc @@ -2566,7 +2566,7 @@ vect_recog_widen_sum_pattern (vec_info *vinfo, Widening with mask first, shift later: container = (type_out) container; masked = container & (((1 << bitsize) - 1) << bitpos); - result = patt2 >> masked; + result = masked >> bitpos; Widening with shift first, mask last: container = (type_out) container; @@ -2578,6 +2578,15 @@ vect_recog_widen_sum_pattern (vec_info *vinfo, result = masked >> bitpos; result = (type_out) result; + If the bitfield is signed and it's wider than type_out, we need to + keep the result sign-extended: + container = (type) container; + masked = container << (prec - bitsize - bitpos); + result = (type_out) (masked >> (prec - bitsize)); + + Here type is the signed variant of the wider of type_out and the type + of container. + The shifting is always optional depending on whether bitpos != 0. */ @@ -2636,14 +2645,22 @@ vect_recog_bitfield_ref_pattern (vec_info *vinfo, stmt_vec_info stmt_info, if (BYTES_BIG_ENDIAN) shift_n = prec - shift_n - mask_width; + bool sign_ext = (!TYPE_UNSIGNED (TREE_TYPE (bf_ref)) && + TYPE_PRECISION (ret_type) > mask_width); + bool widening = ((TYPE_PRECISION (TREE_TYPE (container)) < + TYPE_PRECISION (ret_type)) + && !useless_type_conversion_p (TREE_TYPE (container), + ret_type)); + /* We move the conversion earlier if the loaded type is smaller than the return type to enable the use of widening loads. */ - if (TYPE_PRECISION (TREE_TYPE (container)) < TYPE_PRECISION (ret_type) - && !useless_type_conversion_p (TREE_TYPE (container), ret_type)) + if (sign_ext || widening) { - pattern_stmt - = gimple_build_assign (vect_recog_temp_ssa_var (ret_type), - NOP_EXPR, container); + tree type = widening ? ret_type : container_type; + if (sign_ext) + type = gimple_signed_type (type); + pattern_stmt = gimple_build_assign (vect_recog_temp_ssa_var (type), + NOP_EXPR, container); container = gimple_get_lhs (pattern_stmt); container_type = TREE_TYPE (container); prec = tree_to_uhwi (TYPE_SIZE (container_type)); @@ -2671,7 +2688,7 @@ vect_recog_bitfield_ref_pattern (vec_info *vinfo, stmt_vec_info stmt_info, shift_first = true; tree result; - if (shift_first) + if (shift_first && !sign_ext) { tree shifted = container; if (shift_n) @@ -2694,14 +2711,27 @@ vect_recog_bitfield_ref_pattern (vec_info *vinfo, stmt_vec_info stmt_info, } else { - tree mask = wide_int_to_tree (container_type, - wi::shifted_mask (shift_n, mask_width, - false, prec)); - pattern_stmt - = gimple_build_assign (vect_recog_temp_ssa_var (container_type), - BIT_AND_EXPR, container, mask); - tree masked = gimple_assign_lhs (pattern_stmt); + tree temp = vect_recog_temp_ssa_var (container_type); + if (!sign_ext) + { + tree mask = wide_int_to_tree (container_type, + wi::shifted_mask (shift_n, + mask_width, + false, prec)); + pattern_stmt = gimple_build_assign (temp, BIT_AND_EXPR, + container, mask); + } + else + { + HOST_WIDE_INT shl = prec - shift_n - mask_width; + shift_n += shl; + pattern_stmt = gimple_build_assign (temp, LSHIFT_EXPR, + container, + build_int_cst (sizetype, + shl)); + } + tree masked = gimple_assign_lhs (pattern_stmt); append_pattern_def_seq (vinfo, stmt_info, pattern_stmt, vectype); pattern_stmt = gimple_build_assign (vect_recog_temp_ssa_var (container_type),