From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 188A03857732; Fri, 4 Aug 2023 15:26:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 188A03857732 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1691162811; bh=ACxnF2I5z56c//p5n/JIvGiHqWUntCEO9KvsrVLj80w=; h=From:To:Subject:Date:In-Reply-To:References:From; b=X66eC36VmZY+3IE/iAWD8pXDY6pH24fFLqXBgX8ukt0dHSjeRJuBkJtiWUdnO5d4m UqN73ZMxZTKyqwvCqkdakVABJNClvLxJaha33S/rFC5uxcxBn9xnO1g+/dMW6LZ+ko 7zwYY+BoDvJ5qgUxTsSKsFBb74i8Yf7LfZK18chk= From: "cvs-commit at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug rtl-optimization/110717] Double-word sign-extension missed-optimization Date: Fri, 04 Aug 2023 15:26:50 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: rtl-optimization X-Bugzilla-Version: 14.0 X-Bugzilla-Keywords: missed-optimization X-Bugzilla-Severity: normal X-Bugzilla-Who: cvs-commit at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: 14.0 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D110717 --- Comment #15 from CVS Commits --- The master branch has been updated by Roger Sayle : https://gcc.gnu.org/g:c572f09a751cbd365e2285b30527de5ab9025972 commit r14-2998-gc572f09a751cbd365e2285b30527de5ab9025972 Author: Roger Sayle Date: Fri Aug 4 16:26:06 2023 +0100 Specify signed/unsigned/dontcare in calls to extract_bit_field_1. This patch is inspired by Jakub's work on PR rtl-optimization/110717. The bitfield example described in comment #2, looks like: struct S { __int128 a : 69; }; unsigned type bar (struct S *p) { return p->a; } which on x86_64 with -O2 currently generates: bar: movzbl 8(%rdi), %ecx movq (%rdi), %rax andl $31, %ecx movq %rcx, %rdx salq $59, %rdx sarq $59, %rdx ret The ANDL $31 is interesting... we first extract an unsigned 69-bit bitf= ield by masking/clearing the top bits of the most significant word, and then it gets sign-extended, by left shifting and arithmetic right shifting. Obviously, this bit-wise AND is redundant, for signed bit-fields, we do= n't require these bits to be cleared, if we're about to set them appropriat= ely. This patch eliminates this redundancy in the middle-end, during RTL expansion, but extending the extract_bit_field APIs so that the integer UNSIGNEDP argument takes a special value; 0 indicates the field should be sign extended, 1 (any non-zero value) indicates the field should be zero extended, but -1 indicates a third option, that we don't care how or whether the field is extended. By passing and checking this sentinel value at the appropriate places we avoid the useless bit masking (on all targets). For the test case above, with this patch we now generate: bar: movzbl 8(%rdi), %ecx movq (%rdi), %rax movq %rcx, %rdx salq $59, %rdx sarq $59, %rdx ret 2023-08-04 Roger Sayle gcc/ChangeLog * expmed.cc (extract_bit_field_1): Document that an UNSIGNEDP value of -1 is equivalent to don't care. (extract_integral_bit_field): Indicate that we don't require the most significant word to be zero extended, if we're about to sign extend it. (extract_fixed_bit_field_1): Document that an UNSIGNEDP value of -1 is equivalent to don't care. Don't clear the most significant bits with AND mask when UNSIGNEDP is -1. gcc/testsuite/ChangeLog * gcc.target/i386/pr110717-2.c: New test case.=