From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 72565 invoked by alias); 20 Sep 2015 04:53:32 -0000 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 Received: (qmail 72372 invoked by uid 48); 20 Sep 2015 04:52:51 -0000 From: "olegendo at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug target/67644] New: [SH] double load on volatile bitfield mem Date: Sun, 20 Sep 2015 04:53:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: target X-Bugzilla-Version: unknown X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: olegendo at gcc dot gnu.org X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone cf_gcctarget Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2015-09/txt/msg01570.txt.bz2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67644 Bug ID: 67644 Summary: [SH] double load on volatile bitfield mem Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: olegendo at gcc dot gnu.org Target Milestone: --- Target: sh*-*-* The following: struct USRSTR { union { unsigned char BYTE; struct { unsigned char BIT7:1; unsigned char BIT6:1; unsigned char BIT5:1; unsigned char BIT4:1; unsigned char BIT3:1; unsigned char BIT2:1; unsigned char BIT1:1; unsigned char BIT0:1; } BIT; } ICR0; }; void test_1 (volatile USRSTR* x) { x->ICR0.BIT.BIT5 |= 1; } compiled with -O2 -m4 -ml results in: mov.b @r4,r1 mov.b @r4,r0 or #4,r0 mov.b r0,@r4 rts nop The double load looks wrong. With normal memory it might do no harm, but when accessing hardware registers this might result in wrong behavior. For instance, sometimes hardware register reads clear status bits etc. It seems this happens only when the bitfield is read and written back. If it's only read, there is only one load: int test_2 (volatile USRSTR* x) { return x->ICR0.BIT.BIT5; } mov.b @r4,r0 tst #4,r0 mov #-1,r0 rts negc r0,r0 And it happens only when there are bitfields involved: void test_3 (volatile unsigned char* x) { x[0] |= 4; } mov.b @r4,r0 extu.b r0,r0 or #4,r0 mov.b r0,@r4 rts nop The problem is present on trunk and GCC 5.