Bug 162274 - gcc 4 -O2 sometimes ignores volatile in void context
Summary: gcc 4 -O2 sometimes ignores volatile in void context
Keywords:
Status: CLOSED UPSTREAM
Alias: None
Product: Fedora
Classification: Fedora
Component: gcc
Version: 4
Hardware: x86_64
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks: libvgahw
TreeView+ depends on / blocked
 
Reported: 2005-07-01 20:43 UTC by D. Hugh Redelmeier
Modified: 2007-11-30 22:11 UTC (History)
4 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2005-07-03 12:35:22 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
GNU Compiler Collection 22278 0 None None None Never

Description D. Hugh Redelmeier 2005-07-01 20:43:24 UTC
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.8) Gecko/20050513 Fedora/1.0.4-1.3.1 Firefox/1.0.4

Description of problem:
a reference to a volatile object, even in a void context, should cause an access to that object.  In gcc4, apparently this is not always the case.

"info gcc" node "Volatiles" with title "6.1 When is a Volatile Object Accessed?" clearly says:

<<Less obvious expressions are where something which looks like an access
is used in a void context.  An example would be,

     volatile int *src = SOMEVALUE;
     *src;

 With C, such expressions are rvalues, and as rvalues cause a read of
the object, GCC interprets this as a read of the volatile being pointed
to.>>

This does not match gcc4's behaviour (but earlier gcc versions did follow this rule).

Version-Release number of selected component (if applicable):
gcc-4.0.0-8

How reproducible:
Always

Steps to Reproduce:
1. create a file "gccvolopt.c" with the following code:
typedef unsigned char CARD8;    /* from /usr/include/X11/Xmd.h:150 */

void
test(CARD8 *addr)
{
        *(volatile CARD8 *)addr;
}

2. Examine the output of: cc -S -O2 gccvolopt.c && cat gccvolopt.s

  

Actual Results:  The expression was optimized away: there is no code to fetch *addr

Expected Results:  There should have been a fetch from *addr

Additional info:

see also https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=161242
#56 is where the problem was first isolated.

This gcc change/bug seems to cause a subtle but serious bug in X.


Variations in the sample program cause the fetch to appear or disappear.  For example, the expression "*((volatile CARD8 *)addr + 1);" does cause a fetch to happen.  Changing the 1 to 0 causes the fetch to disappear again.  Adding "volatile" to the parameter definition causes the fetch to appear.

Comment 1 Olivier Baudron 2005-07-02 08:29:06 UTC
It seems to be a bug when casting to a volatile. Below, the first testcase works
whereas the second does not:

void test_1 (volatile char *addr) {
    *addr;
}

void test_2 (char *addr) {
    *((volatile char *) addr);
}

Comment 2 Olivier Baudron 2005-07-02 21:14:36 UTC
I posted my testcase on gcc's bugzilla.
It seems there is a controversy whether this is a gcc bug or not.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22278

Comment 3 redhat-bugs2eran 2005-07-03 07:18:34 UTC
Also related to the following gcc bug (currently closed, IMO wrongly, see
comments there):

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21568


Comment 4 Jakub Jelinek 2005-07-03 12:35:22 UTC
There is no point in tracking this here in addition to upstream.
Fedora GCC closely follows the upstream tree.

Comment 5 Mike A. Harris 2005-07-04 05:45:28 UTC
Jakub:

This bug causes bug #161242 in Xorg, which has a massive number
of duplicates, and prevents users from doing a GUI install, as well as from
being able to properly run X after text install.

There are 3 options I can think of for fixing this:

1) Wait until a fixed gcc is released for FC4 as an official update.

Will there be an official FC4 update to fix this?

or

2) Recompile libvgahw.a with -O0 in %install of xorg-x11 after the rest
   of the build is complete.

This would work around this issue too, but it's possible that this gcc
bug causes problems in other parts of the X server or tree as well.
Recompiling the entire X server with -O0, seems a bad overall solution
to avoid a known compiler bug, and might have really bad performance
concequences (unknown).

or

3) Patch the source for this module to work around the gcc bug.  This
would work around this one specific problem, but again, might leave other
dormant bugs in other parts of the X server which we haven't isolated yet.


The impact of this bug is rather large, as can be seen by the list of
duplicates closed on bug #161242.  I'd just like to get an idea what might
be the best path of closure in the short term, as I'm going to be unavailable
for 3 weeks starting July 16th.   Worst case I think we might go with #2
above if #1 isn't available in time to release an update prior to OLS.

TIA


Comment 6 Jakub Jelinek 2005-07-04 07:40:26 UTC
1) it is not really clear whether this is a bug, see PR22278
2) you have not proven in any way this is the cause of the problem you are
   seeing in libvgahw.a (I have briefly grepped for the use of volatile
   in that library and have not found anything obvious)

Comment 7 Olivier Baudron 2005-07-04 08:47:54 UTC
Proof of 2)

* libvgahw.a is fixed when only mmioReadAttr() (a 10 line function) is compiled
  with -O0
* When mmioReadAttr() is compiled with -O0 and line:
  (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
  is commented, then the same bug as initially reported is observed.
* When the same line in mmioReadAttr() is patched with:
  volatile CARD8 tmp;
  tmp = minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
  Then the bug is fixed when compiling with -O2.
* When comparing the code output by gcc -S and gcc -O2 -S, the only difference
  is that this same line is discarded with -O2.
* This line is preprocessed in:
  (void) *(volatile CARD8 *)(((CARD8*)(hwp->MMIOBase)) + ((hwp->MMIOOffset +
(hwp->IOBase + 0x0A))));
  And this is clearly a dereference to a cast into a volatile qualifier.

Comment 8 Jakub Jelinek 2005-07-04 08:54:54 UTC
Then surely vgaHWRec's MMIOBase field should be
volatile CARD8 * MMIOBase;
instead of
CARD8 * MMIOBase;


Comment 9 D. Hugh Redelmeier 2005-07-18 22:11:47 UTC
This seems to have been declared to be a GCC bug by the GCC folks.  A tentative
fix was posted here:
  http://gcc.gnu.org/ml/gcc/2005-07/msg00733.html

Comment 10 Jakub Jelinek 2005-07-18 22:12:51 UTC
I know.


Note You need to log in before you can comment on or make changes to this bug.