From patchwork Tue Nov 1 11:54:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kyrill Tkachov X-Patchwork-Id: 80330 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp586661qge; Tue, 1 Nov 2016 04:54:55 -0700 (PDT) X-Received: by 10.98.23.88 with SMTP id 85mr27742264pfx.21.1478001295332; Tue, 01 Nov 2016 04:54:55 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id xy7si8744056pac.183.2016.11.01.04.54.55 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 01 Nov 2016 04:54:55 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-440027-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-440027-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-440027-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=aB/Ww72u/h+z+jVvnYTjD95NnWDxZ5d42AZT0/lpKnfLJF +Ap8PwslsL/0B2KVRIF/b7X9r6tPXgwSoy0fYQKm5TjAinvteq+8mJMd926GnSF2 abI3gjEkzGgm1uQ/GuRdGGBc/ufxslafgyLrnru8k3zJCvJiAYRWf4KoitnIQ= 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 :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=c6xk4/6LB5Svsi+lOf6eGS7WPkI=; b=aBwsynS5TyPqSvPk+SCo ClGLWA3F74nRs3z6TGVmN3pCYOqN3E0EMXA7E+FRYXeYCICZoCCd7y9qzFLcu5CS 3ze1ewYQCbzlZFAEfYpxD76VxKhf2Cs9WHQGfMdZBWYy55tVnWDISG95iclUnURK 9I1++zltme7i1j5cAVNqlMI= Received: (qmail 110517 invoked by alias); 1 Nov 2016 11:54:40 -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 110495 invoked by uid 89); 1 Nov 2016 11:54:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.4 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=UD:This, 2016-11-01 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; Tue, 01 Nov 2016 11:54:32 +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 ECCD114D1; Tue, 1 Nov 2016 04:54:30 -0700 (PDT) Received: from [10.2.207.77] (e100706-lin.cambridge.arm.com [10.2.207.77]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9FA213F318 for ; Tue, 1 Nov 2016 04:54:30 -0700 (PDT) Message-ID: <58188275.2080000@foss.arm.com> Date: Tue, 01 Nov 2016 11:54:29 +0000 From: Kyrill Tkachov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: GCC Patches Subject: [PATCH] PR tree-optimization/78170: Truncate sign-extended padding when encoding bitfields Hi all, In this PR the code writes a -1 to a bitfield of size 17 bits and ends up overwriting another bitfields. The problem is that the intermediate buffer in encode_tree_to_bitpos holding the value to merge holds a 24-bit temporary with -1 written to it i.e. sign-extended to all ones. That is how native_encode_expr works.This gets then written to the final buffer (well, a shifted version of it). We should instead be truncating the intermediate value to contain zeros in all the bits that we don't want. This is already performed for big-endian, this patch just wires it up for little-endian. Bootstrapped and tested on x86_64. Ok for trunk? Thanks, Kyrill 2016-11-01 Kyrylo Tkachov PR tree-optimization/78170 * gimple-ssa-store-merging.c (encode_tree_to_bitpos): Truncate padding introduced by native_encode_expr on little-endian as well. 2016-11-01 Kyrylo Tkachov PR tree-optimization/78170 * gcc.c-torture/execute/pr78170.c: New test. diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c index 5a293d7f30735499aafebeb935b073946eab5691..f82cad35afbc10eea76957d38100acdce137d271 100644 --- a/gcc/gimple-ssa-store-merging.c +++ b/gcc/gimple-ssa-store-merging.c @@ -432,13 +432,23 @@ encode_tree_to_bitpos (tree expr, unsigned char *ptr, int bitlen, int bitpos, contain a sign bit due to sign-extension). */ unsigned int padding = byte_size - ROUND_UP (bitlen, BITS_PER_UNIT) / BITS_PER_UNIT - 1; - if (BYTES_BIG_ENDIAN) + if (padding != 0) { - tmpbuf += padding; + /* On big-endian the padding is at the 'front' so just skip the initial + bytes. */ + if (BYTES_BIG_ENDIAN) + tmpbuf += padding; + byte_size -= padding; if (bitlen % BITS_PER_UNIT != 0) - clear_bit_region_be (tmpbuf, BITS_PER_UNIT - 1, - BITS_PER_UNIT - (bitlen % BITS_PER_UNIT)); + { + if (BYTES_BIG_ENDIAN) + clear_bit_region_be (tmpbuf, BITS_PER_UNIT - 1, + BITS_PER_UNIT - (bitlen % BITS_PER_UNIT)); + else + clear_bit_region (tmpbuf, bitlen, + byte_size * BITS_PER_UNIT - bitlen); + } } /* Clear the bit region in PTR where the bits from TMPBUF will be diff --git a/gcc/testsuite/gcc.c-torture/execute/pr78170.c b/gcc/testsuite/gcc.c-torture/execute/pr78170.c new file mode 100644 index 0000000000000000000000000000000000000000..8ef812ee6accb62db8dd6889d74032a88b784d2c --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr78170.c @@ -0,0 +1,37 @@ +/* PR tree-optimization/78170. + Check that sign-extended store to a bitfield + doesn't overwrite other fields. */ + +int a, b, d; + +struct S0 +{ + int f0; + int f1; + int f2; + int f3; + int f4; + int f5:15; + int f6:17; + int f7:2; + int f8:30; +} c; + +void fn1 () +{ + d = b = 1; + for (; b; b = a) + { + struct S0 e = { 0, 0, 0, 0, 0, 0, 1, 0, 1 }; + c = e; + c.f6 = -1; + } +} + +int main () +{ + fn1 (); + if (c.f7 != 0) + __builtin_abort (); + return 0; +}