From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6441 invoked by alias); 1 Feb 2012 11:13:29 -0000 Received: (qmail 6431 invoked by uid 22791); 1 Feb 2012 11:13:28 -0000 X-SWARE-Spam-Status: No, hits=-2.9 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from localhost (HELO gcc.gnu.org) (127.0.0.1) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 01 Feb 2012 11:13:15 +0000 From: "rguenth at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug target/52080] Stores to bitfields introduce a store-data-race on adjacent data Date: Wed, 01 Feb 2012 11:13:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: target X-Bugzilla-Keywords: wrong-code X-Bugzilla-Severity: normal X-Bugzilla-Who: rguenth at gcc dot gnu.org X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2012-02/txt/msg00050.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52080 --- Comment #4 from Richard Guenther 2012-02-01 11:12:41 UTC --- Btw, offset = bitnum / unit; bitpos = bitnum % unit; byte_offset = (bitnum % BITS_PER_WORD) / BITS_PER_UNIT + (offset * UNITS_PER_WORD); byte_offset is bollocks (or has a really poor name). On SPARC64 I see (gdb) p unit $11 = 8 (gdb) p offset $12 = 12 (gdb) p bitpos $13 = 0 (gdb) p byte_offset $14 = 100 Other than that we are falling into the generic store_fixed_bit_field routine which at the top does unsigned int total_bits = BITS_PER_WORD; and mode = GET_MODE (op0); if (GET_MODE_BITSIZE (mode) == 0 || GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (word_mode)) mode = word_mode; (now, why we use a BLKmode mem here and not a QImode mem may be surprising) get_best_mode still returns DImode because that's the largest mode the given alignment supports. After that we're lost. So it seems that to fix this case we'd need to figure out some other largest mode we can pass to get_best_mode. The only hint would be from providing a different mode for the initial MEM we create, like with Index: gcc/expr.c =================================================================== --- gcc/expr.c (revision 183791) +++ gcc/expr.c (working copy) @@ -4705,6 +4705,12 @@ expand_assignment (tree to, tree from, b to_rtx = adjust_address (to_rtx, mode1, 0); else if (GET_MODE (to_rtx) == VOIDmode) to_rtx = adjust_address (to_rtx, BLKmode, 0); + else if (TREE_CODE (to) == COMPONENT_REF + && DECL_BIT_FIELD (TREE_OPERAND (to, 1)) + && DECL_MODE (TREE_OPERAND (to, 1)) != BLKmode) + to_rtx = adjust_address (to_rtx, + TYPE_MODE (DECL_BIT_FIELD_TYPE + (TREE_OPERAND (to, 1))), 0); } if (offset != 0) That avoids the use of QImode we have on the field-decl but also adjusts MEM_SIZE ...