I've recently upgraded to GCC 4.3.2 from 4.2.2, and I noticed a strange change in how volatile bitmask structures are optimized. Consider the following code (compiled using just the -O3 option): /* 32-bit MMIO */ struct hardware { int parm1:8; int :4; int parm2:4; int parm3:15; int parm4:1; }; void f1() { volatile struct hardware *ptr=(void *)0x11223344; *ptr=(struct hardware) { .parm1=42, .parm2=13, .parm3=11850, .parm4=1, }; } void f2() { volatile struct hardware *ptr=(void *)0x11223344; struct hardware set={ .parm1=42, .parm2=13, .parm3=11850, .parm4=1, }; *ptr=set; } In GCC 4.3.2, this produces the following assembly: f1: movl $0, 287454020 movb $42, 287454020 movl 287454020, %eax andb $15, %ah orb $208, %ah movl %eax, 287454020 movl 287454020, %eax andl $-2147418113, %eax orl $776601600, %eax movl %eax, 287454020 movl 287454020, %eax orl $-2147483648, %eax movl %eax, 287454020 ret f2: movl $-1370828758, 287454020 ret Aren't both functions syntactically the same, and shouldn't they produce the same optimized code as in "f2" above? This used to be the case in GCC 4.2.2. The problem I'm seeing, apart from the lack of optimization, is that "f1" causes 5 separate writes to a single MMIO register, instead of 1. This particular hardware register is only expecting one write to this location, and when multiple writes are received it causes the hardware to fail. If this new behavior is intended, is there some sort of attribute I can add to the code to get the original 4.2.2 behavior back? Thanks, -Byron
Confirmed, I think this was caused/exposed by: 2007-11-20 Jakub Jelinek <jakub@redhat.com> PR c/34146 * c-gimplify.c (optimize_compound_literals_in_ctor): New function. (c_gimplify_expr): Use it.
Yep: f2 () { volatile struct hardware * ptr; struct hardware set; ptr = 287454020B; set = {}; set.parm1 = 42; set.parm2 = -3; set.parm3 = 11850; set.parm4 = -1; *ptr = set; } f1 () { volatile struct hardware * ptr; ptr = 287454020B; *ptr = {}; ptr->parm1 = 42; ptr->parm2 = -3; ptr->parm3 = 11850; ptr->parm4 = -1; } we need to gimplify f1 exactly the same as f2, using a temporary.
I will have a look.
Martin - we recently regressed here due to SRA. Even for f2 we now decompose the assigment to *ptr, even though that will create extra volatile accesses. I have a patch for the gimplifier bits (to be attached).
Created attachment 19759 [details] patch
The patch provided fixes this issue and brings the original GCC 4.2.2 behavior back. Thanks so much for your quick response!
Subject: Re: [4.3/4.4/4.5 Regression] volatile structures and compound literal initializers On Sat, 30 Jan 2010, gandalf at winds dot org wrote: > ------- Comment #6 from gandalf at winds dot org 2010-01-30 20:56 ------- > The patch provided fixes this issue and brings the original GCC 4.2.2 behavior > back. Not yet for 4.5 though. Richard. > Thanks so much for your quick response!
Subject: Bug 42898 Author: rguenth Date: Sun Jan 31 17:01:38 2010 New Revision: 156404 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=156404 Log: 2010-01-31 Richard Guenther <rguenther@suse.de> PR middle-end/42898 * gimplify.c (gimplify_init_constructor): For volatile LHS initialize a temporary. * gcc.dg/torture/pr42898.c: New testcase. Added: trunk/gcc/testsuite/gcc.dg/torture/pr42898.c Modified: trunk/gcc/ChangeLog trunk/gcc/gimplify.c trunk/gcc/testsuite/ChangeLog
Subject: Bug 42898 Author: rguenth Date: Sun Jan 31 17:04:29 2010 New Revision: 156405 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=156405 Log: 2010-01-31 Richard Guenther <rguenther@suse.de> PR middle-end/42898 * gimplify.c (gimplify_init_constructor): For volatile LHS initialize a temporary. * gcc.dg/torture/pr42898.c: New testcase. Added: branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/torture/pr42898.c Modified: branches/gcc-4_4-branch/gcc/ChangeLog branches/gcc-4_4-branch/gcc/gimplify.c branches/gcc-4_4-branch/gcc/testsuite/ChangeLog
Subject: Bug 42898 Author: rguenth Date: Sun Jan 31 17:07:16 2010 New Revision: 156407 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=156407 Log: 2010-01-31 Richard Guenther <rguenther@suse.de> PR middle-end/42898 * gimplify.c (gimplify_init_constructor): For volatile LHS initialize a temporary. * gcc.dg/torture/pr42898.c: New testcase. Added: branches/gcc-4_3-branch/gcc/testsuite/gcc.dg/torture/pr42898.c Modified: branches/gcc-4_3-branch/gcc/ChangeLog branches/gcc-4_3-branch/gcc/gimplify.c branches/gcc-4_3-branch/gcc/testsuite/ChangeLog
Fixed on the branches. Trunk is still broken because of SRA, reassigning to Martin for that.
Subject: Bug 42898 Author: ebotcazou Date: Sun Jan 31 20:00:54 2010 New Revision: 156414 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=156414 Log: PR middle-end/42898 * gcc.dg/torture/pr42898-2.c: New test. Added: trunk/gcc/testsuite/gcc.dg/torture/pr42898-2.c Modified: trunk/gcc/testsuite/ChangeLog
Subject: Bug 42898 Author: ebotcazou Date: Sun Jan 31 21:06:20 2010 New Revision: 156415 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=156415 Log: PR middle-end/42898 Backport from mainline: 2009-04-23 Eric Botcazou <ebotcazou@adacore.com> * gimplify.c (gimplify_modify_expr_rhs) <VAR_DECL>: Do not do a direct assignment from the constructor either if the target is volatile. Added: branches/gcc-4_4-branch/gcc/testsuite/gcc.dg/torture/pr42898-2.c Modified: branches/gcc-4_4-branch/gcc/ChangeLog branches/gcc-4_4-branch/gcc/gimplify.c branches/gcc-4_4-branch/gcc/testsuite/ChangeLog
Subject: Bug 42898 Author: ebotcazou Date: Sun Jan 31 21:08:15 2010 New Revision: 156416 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=156416 Log: 2010-01-31 Eric Botcazou <ebotcazou@adacore.com> PR middle-end/42898 Backport from mainline: 2009-04-23 Eric Botcazou <ebotcazou@adacore.com> * gimplify.c (gimplify_modify_expr_rhs) <VAR_DECL>: Do not do a direct assignment from the constructor either if the target is volatile. Added: branches/gcc-4_3-branch/gcc/testsuite/gcc.dg/torture/pr42898-2.c Modified: branches/gcc-4_3-branch/gcc/ChangeLog branches/gcc-4_3-branch/gcc/gimplify.c branches/gcc-4_3-branch/gcc/testsuite/ChangeLog
The new gcc.dg/torture/pr42898.c fails on x86_64-apple-darwin10... FAIL: gcc.dg/torture/pr42898.c -O1 scan-tree-dump-times optimized "\*ptr" 1 FAIL: gcc.dg/torture/pr42898.c -O2 scan-tree-dump-times optimized "\*ptr" 1 FAIL: gcc.dg/torture/pr42898.c -O3 -fomit-frame-pointer scan-tree-dump-times optimized "\*ptr" 1 FAIL: gcc.dg/torture/pr42898.c -O3 -g scan-tree-dump-times optimized "\*ptr" 1 FAIL: gcc.dg/torture/pr42898.c -Os scan-tree-dump-times optimized "\*ptr" 1
Created attachment 19772 [details] assembly for gcc.dg/torture/pr42898.c -O1 on x86_64-apple-darwin10 /sw/src/fink.build/gcc45-4.4.999-20100131/darwin_objdir/gcc/xgcc -B/sw/src/fink.build/gcc45-4.4.999-20100131/darwin_objdir/gcc/ /sw/src/fink.build/gcc45-4.4.999-20100131/gcc-4.5-20100131/gcc/testsuite/gcc.dg/torture/pr42898.c -O1 -fdump-tree-optimized -S -o pr42898.s
Created attachment 19773 [details] .optimized for gcc.dg/torture/pr42898.c -O1 on x86_64-apple-darwin10
See comment #11
Created attachment 19807 [details] Patch disallowing piecemeal and total scalarization in presence of volatile ops I'm currently bootstrapping and testing this patch.
Subject: Bug 42898 Author: jamborm Date: Mon Feb 8 13:24:12 2010 New Revision: 156599 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=156599 Log: 2010-02-08 Martin Jambor <mjambor@suse.cz> PR middle-end/42898 * tree-sra.c (build_accesses_from_assign): Do not mark in should_scalarize_away_bitmap if stmt has volatile ops. (sra_modify_assign): Do not process assigns piecemeal if if stmt has volatile ops. Modified: trunk/gcc/ChangeLog trunk/gcc/tree-sra.c
The testcase now passes. The issue is fixed.
*** Bug 43003 has been marked as a duplicate of this bug. ***