Bug 42898 - [4.5 Regression] volatile structures and compound literal initializers
Summary: [4.5 Regression] volatile structures and compound literal initializers
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.3.2
: P1 normal
Target Milestone: 4.3.5
Assignee: Martin Jambor
URL:
Keywords: wrong-code
: 43003 (view as bug list)
Depends on:
Blocks:
 
Reported: 2010-01-29 19:27 UTC by gandalf
Modified: 2010-02-08 22:36 UTC (History)
5 users (show)

See Also:
Host: x86_64-pc-linux-gnu
Target: x86_64-pc-linux-gnu
Build: x86_64-pc-linux-gnu
Known to work: 4.3.5 4.4.4
Known to fail:
Last reconfirmed: 2010-01-29 22:42:15


Attachments
patch (898 bytes, patch)
2010-01-30 18:17 UTC, Richard Biener
Details | Diff
assembly for gcc.dg/torture/pr42898.c -O1 on x86_64-apple-darwin10 (454 bytes, text/plain)
2010-02-01 01:50 UTC, Jack Howarth
Details
.optimized for gcc.dg/torture/pr42898.c -O1 on x86_64-apple-darwin10 (141 bytes, text/plain)
2010-02-01 01:54 UTC, Jack Howarth
Details
Patch disallowing piecemeal and total scalarization in presence of volatile ops (593 bytes, patch)
2010-02-05 14:40 UTC, Martin Jambor
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description gandalf 2010-01-29 19:27:37 UTC
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
Comment 1 Andrew Pinski 2010-01-29 19:38:02 UTC
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.
Comment 2 Richard Biener 2010-01-29 22:41:34 UTC
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.
Comment 3 Richard Biener 2010-01-29 22:42:15 UTC
I will have a look.
Comment 4 Richard Biener 2010-01-30 18:08:59 UTC
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).
Comment 5 Richard Biener 2010-01-30 18:17:00 UTC
Created attachment 19759 [details]
patch
Comment 6 gandalf 2010-01-30 20:56:18 UTC
The patch provided fixes this issue and brings the original GCC 4.2.2 behavior back.

Thanks so much for your quick response!
Comment 7 rguenther@suse.de 2010-01-30 21:25:39 UTC
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!

Comment 8 Richard Biener 2010-01-31 17:01:53 UTC
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

Comment 9 Richard Biener 2010-01-31 17:04:42 UTC
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

Comment 10 Richard Biener 2010-01-31 17:07:27 UTC
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

Comment 11 Richard Biener 2010-01-31 17:08:52 UTC
Fixed on the branches.  Trunk is still broken because of SRA, reassigning to
Martin for that.
Comment 12 Eric Botcazou 2010-01-31 20:01:07 UTC
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

Comment 13 Eric Botcazou 2010-01-31 21:06:32 UTC
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

Comment 14 Eric Botcazou 2010-01-31 21:08:25 UTC
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

Comment 15 Jack Howarth 2010-02-01 01:47:29 UTC
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
Comment 16 Jack Howarth 2010-02-01 01:50:50 UTC
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
Comment 17 Jack Howarth 2010-02-01 01:54:16 UTC
Created attachment 19773 [details]
.optimized for gcc.dg/torture/pr42898.c  -O1 on x86_64-apple-darwin10
Comment 18 Michael Matz 2010-02-01 03:13:21 UTC
See comment #11
Comment 19 Martin Jambor 2010-02-05 14:40:31 UTC
Created attachment 19807 [details]
Patch disallowing piecemeal and total scalarization in presence of volatile ops

I'm currently bootstrapping and testing this patch.
Comment 20 Martin Jambor 2010-02-08 13:24:32 UTC
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

Comment 21 Martin Jambor 2010-02-08 13:31:51 UTC
The testcase now passes.  The issue is fixed.
Comment 22 Andrew Pinski 2010-02-08 22:36:06 UTC
*** Bug 43003 has been marked as a duplicate of this bug. ***