This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [-ftree-cselim desoptimizes SH code
Michael Matz <matz@suse.de> writes:
>> I believe this transformation is invalid under the C++0x memory model.
>
> Well, if we choose to support this less than thrilling memory model then
> we possibly have to disable the pass (or limit it) for C++0x, as well as
> the vectorizer (and probably some other passes). No reason that other
> languages have to suffer from the c++ committees decision to ignore
> volatile and barriers to the disfavor of optimizing compilers.
I haven't looked at the code so I don't know if the example correctly
represents what gcc does. However, the example as stated was:
foo(int *a)
{
*a = 0;
if (bar())
*a = 1;
}
into
foo(int *a)
{
*a = 0;
if (! bar())
r = *a;
else
r = 1;
*a = r;
}
This transformation is not OK if a is locked at the start of foo and
if bar looks like this:
bool
bar()
{
if (some_condition)
return true; /* a is still locked. */
unlock_a();
return false;
}
If bar looks like that, then in the second foo example above there is
a race condition when bar returns false, because the assignment to *a
at the end of foo may overwrite an assignment which occurred between
the call to unlock_a and the assignment to *a.
Clearly this can be solved by making 'a' a pointer to volatile memory.
The question here is whether one is required to make 'a' volatile.
After all, we can assume that unlock_a has a memory barrier. Does a
correct C/C++ program require making all shared variables volatile?
Note in particular that we have already decided to disallow
speculative stores in ifcvt.c (see noce_can_store_speculate_p). If
tree-cselim does indeed cause speculative stores as the OP asserts,
then I think we should disable that too.
Ian