This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Spurious register spill with volatile function argument
- From: Florian Weimer <fw at deneb dot enyo dot de>
- To: Andrew Haley <aph at redhat dot com>
- Cc: Michael Clark <michaeljclark at mac dot com>, gcc at gcc dot gnu dot org, cfe-dev at lists dot llvm dot org, Andrew Waterman <andrew at sifive dot com>, RISC-V Software Developers <sw-dev at groups dot riscv dot org>
- Date: Mon, 28 Mar 2016 14:11:58 +0200
- Subject: Re: Spurious register spill with volatile function argument
- Authentication-results: sourceware.org; auth=none
- References: <2600D96D-94BC-4259-9D39-DE4993859281 at mac dot com> <9F3C9DE6-F00B-4402-A83B-354455DEAFFA at mac dot com> <CA++6G0CK3Yu-w9fhOrvpRP49qz9=Vs20J_=R28Mq=zCJOH+-UA at mail dot gmail dot com> <238543C3-39EA-4D5D-8C54-631BF796A38B at mac dot com> <56F8F66D dot 6020002 at redhat dot com>
* Andrew Haley:
> "volatile" doesn't really mean very much, formally speaking. Sure, the
> standard says "accesses to volatile objects are evaluated
> strictly according to the rules of the abstract machine," but nowhere
> is it specified exactly what constitutes an access.
Reading or modifying an object is defined as âaccessâ.
The problem is that âreadingâ is either not defined, or the existing
flatly contradicts existing practice.
For example, if p is a pointer to a struct, will the expression &p->m
read *p?
Previously, this wasn't very interesting. But under the model memory,
it's suddenly quite relevant. If reading p->m implies a read of the
entire object *p, you cannot use a member to synchronize access to
other members of the struct. For example, if m is a mutex, and
carefully acquire the mutex before you read or write other members,
you still have data race between a write to some other member and the
acquisition of the mutex because the mutex acquisition reads the
entire struct (including the member written to ).
One possible cure is to take the address of the mutex and keep track
of it separately. Or you could construct a pointer using offsetof.
But no one is doing that, obviously.
This is not entirely hypothetical. Even today, GCC's aliasing
analysis requires that those implicit whole-object reads take place,
to make certain forms of type-punning invalid which would otherwise be
well-defined (and for which GCC would generate invalid code).